[关闭]
@nextleaf 2018-09-25T20:55:39.000000Z 字数 17102 阅读 997

2018-09-19 工作日志

Java servlet session 四大域


JavaWeb四大域对象

一、ServletContext

相关对象:jsp隐含对象application(javax.servlet.ServletContext类的实例)

 1、生命周期:当Web应用被加载进容器时创建代表整个web应用的ServletContext对象,当服务器关闭或Web应用被移除时,ServletContext对象跟着销毁。

 2、作用范围:整个Web应用。

 3、作用:

a)在不同Servlet 之间转发

  1. this.getServletContext().getRequestDispatcher("/servlet/Demo10Servlet").forward(request,response);

b)读取资源文件。

二、Request 域

  1、生命周期:在service 方法调用前由服务器创建,传入service方法。整个请求结束,request生命结束。

  2、作用范围:整个请求链(请求转发也存在)。

  3、作用:在整个请求链中共享数据。最常用到:在Servlet中处理好的数据交给Jsp显示,此时参数就可以放置在Request域中带过去。

三、Session 域

 HttpSession在服务器中,为浏览器创建独一无二的内存空间,在其中保存会话相关的信息。

1、生命周期:在第一次调用 request.getSession() 方法时,服务器会检查是否已经有对应的session,如果没有就在内存 中创建一个session并返回。

当一段时间内session没有被使用(默认为30分钟),则服务器会销毁该session。如果服务器非正常关闭(强行关闭),没有到期的session也会跟着销毁。

如果调用session提供的invalidate() ,可以立即销毁session。

注意:服务器正常关闭,再启动,Session对象会进行钝化和活化操作。同时如果服务器钝化的时间在session 默认销毁时间之内,则活化后session还是存在的。否则Session不存在。

如果JavaBean 数据在session钝化时,没有实现Serializable则当Session活化时,会消失。

2、作用范围:一次会话。

四、PageContext 域

相关对象:JSP引号对象pageContext(javax.servlet.jsp.PageContext类的实例)

  1、生命周期:当对JSP的请求时开始,当响应结束时销毁。

  2、作用范围:整个JSP页面,是四大作用域中最小的一个。

    作用:

    (1)获取其它八大隐式对象,可以认为是一个入口对象。

    (2)获取其所有域中的数据 

pageContext操作所有域中属性的方法:

  1. public java.lang.ObjectgetAttribute(java.lang.Stringname,intscope)
  2. public void setAttribute(java.lang.String name, java.lang.Object value,intscope)
  3. public voidremoveAttribute(java.lang.Stringname,intscope)

pageContext 中代表域的常量

  1. PageContext.APPLICATION_SCOPE
  2. PageContext.SESSION_SCOPE
  3. PageContext.REQUEST_SCOPE
  4. PageContext.PAGE_SCOPE

findAttribute方法,在四大域中搜寻属性,搜寻的顺序是page域、request域、session域、application域,从小域到大域开始搜索,如果搜索到就直接获取该值,如果所有域中都找不到,返回一个null(与el表达式不同,此处返回null,对网页是不友好的)。
 (3)跳转到其他资源其身上提供了forward和include方法,简化重定向和转发的操作。


上午

session(由HttpSession接口创建)

session在某server端程序调用HttpServletRequest.getSession(true)这样的语句时才被创建
浏览器发出请求
servlet判断cookie消息头中是否有sessionID
如果没有,生成一个,加入到响应头中。
如果有,servlet容器根据此标识查找对应的session对象,如果找到了,且该session对象没有过期,会将此session绑定到此次请求的request对象;如果没找到或者找到的是过期的session对象,则创建新的session,分配新的标识符,同时发送Set-cookie头通知客户端开始保持新的会话。

session是区分客户端的

获取

服务端程序决定何时创建session
1. HttpServletRequest.getSession()被调用,生成全局唯一标识符(sessionid);
2. 开辟数据存储空间。一般会在内存中创建相应的数据结构,但这种情况下,系统一旦掉电,所有的会话数据就会丢失,如果是电子商务网站,这种事故会造成严重的后果。不过也可以写到文件里甚至存储在数据库中,这样虽然会增加I/O开销,但session可以实现某种程度的持久化,而且更有利于session的共享;
3. 将session的全局唯一标示符发送给客户端。

如果客户端禁用了cookie的话,会话保持的实现首选URL重写。

HttpServletRequest.getSession(ture)
若存在会话则返回该会话,否则新建一个会话,等同于HttpServletRequest.getSession()。

HttpServletRequest.getSession(false)
若存在会话则返回该会话,否则返回NULL;

当向Session中存取登录信息时,一般建议:HttpSession session =request.getSession();
当从Session中获取登录信息时,一般建议:HttpSession session =request.getSession(false);

绑定数据

过期时间

session(HttpSession类的实例)的优点

cookie和session

cookie和session二者都能记录状态,cookie是将状态数据保存在客户端,session则保存在服务端。
cookie总数量有限制,每个域名下Cookie个数也有限制,而每个cookie的大小也有限制(通常是4K)
只要HTTP响应中包含如下形式的头,则视为服务器要求客户端设置一个cookie:
Set-cookie:name=name;expires=date;path=path;domain=domain
支持且接收cookie的客户端会创建cookie文件并保存(也可能是内存cookie),用户以后在每次发出请求时,浏览器都要判断当前所有的cookie中有没有没失效(根据expires属性判断)并且匹配了path属性的cookie信息,如果有的话,会以下面的形式加入到请求头中发回服务端:
Cookie: name="zj"; Path="/linkage"
服务端的动态脚本会对其进行分析,并做出相应的处理,当然也可以选择直接忽略。

user表结构

  1. //mysql不支持Date类型设置默认值,这里用varchar代替
  2. CREATE TABLE `javabasedemo`.`user` (
  3. `username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  4. `password` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  5. `birthday` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '1970-01-01',
  6. PRIMARY KEY (`username`) USING BTREE
  7. ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

下午

Strust2

WebWork 2,一个简洁的、可扩展的Java模型 - 视图 - 控制器(MVC)框架
https://www.w3cschool.cn/struts_2/
https://www.cnblogs.com/konrad/p/6426790.html
https://www.w3cschool.cn/struts_2/

基于Struts2框架的分页技术

https://blog.csdn.net/qq_23703157/article/details/53576831

JSTL

核心标签

标签 描述
<c:out> 用于在JSP中显示数据,就像<%= ... >
<c:set> 用于保存数据
<c:remove> 用于删除数据
<c:catch> 用来处理产生错误的异常状况,并且将错误信息储存起来
<c:if> 与我们在一般程序中用的if一样
<c:choose> 本身只当做<c:when>和<c:otherwise>的父标签
<c:when> <c:choose>的子标签,用来判断条件是否成立
<c:otherwise> <c:choose>的子标签,接在<c:when>标签后,当<c:when>标签判断为false时被执行
<c:import> 检索一个绝对或相对 URL,然后将其内容暴露给页面
<c:forEach> 基础迭代标签,接受多种集合类型
<c:forTokens> 根据指定的分隔符来分隔内容并迭代输出
<c:param> 用来给包含或重定向的页面传递参数
<c:redirect> 重定向至一个新的URL.
<c:url> 使用可选的查询参数来创造一个URL

引用核心标签库

  1. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  2. <!--uri命名空间-->

  1. <%@ page import="s.entity.User" %>
  2. <%@ page import="java.time.LocalDate" %>
  3. <%@ page import="java.util.ArrayList" %>
  4. <%@ page import="java.util.Arrays" %>
  5. <%@ page import="s.entity.Book" %>
  6. <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
  7. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  8. <html>
  9. <head>
  10. <title>JSTL</title>
  11. <style>
  12. td{
  13. text-align: center;
  14. }
  15. .row1{
  16. background-color: gainsboro;
  17. }
  18. .row2{
  19. background-color: darkgray;
  20. }
  21. </style>
  22. </head>
  23. <body>
  24. <%
  25. User user = new User("黄昭鸿", "密码", LocalDate.now());
  26. request.setAttribute("u1", user);
  27. ArrayList<Book> bookslist = new ArrayList<Book>(
  28. Arrays.asList(
  29. new Book("武侠小说", "天龙八部", "查良镛", 2005, 95.2, "小说以宋哲宗时代为背景,通过宋、辽、大理、西夏、吐蕃等王国之间的武林恩怨和民族矛盾,从哲学的高度对人生和社会进行审视和描写,展示了一幅波澜壮阔的生活画卷,其故事之离奇曲折、涉及人物之众多、历史背景之广泛、武侠战役之庞大、想象力之丰富当属“金书”之最。"),
  30. new Book("武侠小说", "笑傲江湖", "查良镛", 1969, 75.3, "其所折射中国人独特的政治斗争,同时也表露对斗争的哀叹,具有一定的政治寓意。"),
  31. new Book("武侠小说", "倚天屠龙记", "查良镛", 1962, 71.7, "以安徽农民朱元璋揭竿而起建立明朝天下为背景,以张无忌的成长为线索,叙写江湖上的各帮各派、各种人物的恩怨情仇,它把中国历史上元朝的兴衰和江湖道义、恩仇平行交叉起来。"),
  32. new Book("武侠小说", "神雕侠侣", "查良镛", 1961, 74.5, "“叛国贼”杨康之遗孤杨过与其师小龙女之间的爱情故事。"))
  33. );
  34. request.setAttribute("bookslist", bookslist);
  35. %>
  36. <div>
  37. <p>姓名:${u1.username}</p>
  38. <p>密码:${u1.password}</p>
  39. <p>生日:${u1.birthday}</p>
  40. </div>
  41. <c:if test="${u1.username.length()>3}">长名字</c:if>
  42. <c:if test="${u1.username.length()<=3}">短名字</c:if>
  43. <c:choose>
  44. <c:when test="${u1.username.length()>3}"> 长</c:when>
  45. <c:otherwise></c:otherwise>
  46. </c:choose>
  47. <hr>
  48. <div>
  49. <table cellspacing="0" cellpadding="0" border="1">
  50. <caption>书列表</caption>
  51. <tr>
  52. <td>分类</td>
  53. <td>书名</td>
  54. <td>作者</td>
  55. <td>年份</td>
  56. <td>价格</td>
  57. <td width="70%">简介</td>
  58. <td>下标</td>
  59. <td>次数</td>
  60. </tr>
  61. <c:forEach var="book" items="${bookslist}" varStatus="vs">
  62. <tr class="row${(vs.index%2+1)}">
  63. <td>${book.category}</td>
  64. <td>${book.title}</td>
  65. <td>${book.author}</td>
  66. <td>${book.year}</td>
  67. <td>${book.price}</td>
  68. <td>${book.synopsis}</td>
  69. <td>${vs.index}</td>
  70. <td>${vs.count}</td>
  71. </tr>
  72. </c:forEach>
  73. </table>
  74. </div>
  75. <hr>
  76. <div><p>ServerInfo:</p>
  77. <p><%=request.getSession().getServletContext().getAttribute("serverInfo")%></p>
  78. </div>
  79. <hr>
  80. </body>
  81. </html>

依赖:

  1. <!-- https://mvnrepository.com/artifact/jstl/jstl -->
  2. <dependency>
  3. <groupId>jstl</groupId>
  4. <artifactId>jstl</artifactId>
  5. <version>1.2</version>
  6. </dependency>
  7. <!-- https://mvnrepository.com/artifact/taglibs/standard -->
  8. <dependency>
  9. <groupId>taglibs</groupId>
  10. <artifactId>standard</artifactId>
  11. <version>1.1.2</version>
  12. </dependency>

常用的几个核心标签

c:out标签

<c:out>标签用来显示一个表达式的结果,与<%=%>作用相似,它们的区别就是<c:out>标签可以直接通过"."操作符来访问属性。
举例来说,如果想要访问customer.address.street,只需要这样写:<c:out value="customer.address.street">
<c:out>标签会自动忽略XML标记字符,所以它们不会被当做标签来处理
语法:

  1. <c:out value="<string>" default="<string>" escapeXml="<true|false>"/>

属性:

属性 描述 是否必要 默认值
value 要输出的内容
default 输出的默认值 主体中的内容
escapeXml 是否忽略XML特殊字符 true

c:set标签,用于设置变量值和对象属性,绑定空间

语法:

  1. <c:set
  2. var="<string>"
  3. value="<string>"
  4. target="<string>"
  5. property="<string>"
  6. scope="<string>"/>

属性:

属性 描述 是否必要 默认值
value 要存储的值 主体的内容
target 要修改的属性所属的对象
property 要修改的属性
var 存储信息的变量
scope var属性的作用域 Page

如果指定了target属性,那么property属性也需要被指定。

c:remove,用于移除一个变量,移除对象的属性,

可以指定这个变量的作用域,若未指定,则默认为变量第一次出现的作用域。
语法:

  1. <c:remove var="<string>" scope="<string>"/>

属性:

属性 描述 是否必要 默认值
var 要移除的变量名称
scope 变量所属的作用域 所有作用域

c:if 标签

判断表达式的值,如果表达式的值为 true 则执行其主体内容
语法:

  1. <c:if test="<boolean>" var="<string>" scope="<string>">
  2. ...
  3. </c:if>

属性

属性 描述 是否必要 默认值
test 条件
var 用于存储条件结果的变量
scope var属性的作用域 page

例子:模拟 if-else:

  1. <c:if test="${salary > 2000}" var="flag" scope="session">
  2. <p>我的工资为: <c:out value="${salary}"/><p>
  3. </c:if>
  4. <c:if test="${not flag}">
  5. <p>我的工资为: <c:out value="${salary}"/><p>
  6. </c:if>

<c:forEach>, <c:forTokens>标签

  1. scope 的作用域大小依次为:
    application > session > request > page(默认)
  2. jsp 处理变量的作用域先后依次为:
    page(默认) -> request -> session -> application

JSP表达式语言(EL)

  1. ${expr}

EL中的基础操作符

操作符 描述
. 访问一个Bean属性或者一个映射条目
[] 访问一个数组或者链表的元素
( ) 组织一个子表达式以改变优先级
+
- 减或负
*
/ or div
% or mod 取模
== or eq 测试是否相等
!= or ne 测试是否不等
< or lt 测试是否小于
> or gt 测试是否大于
<= or le 测试是否小于等于
>= or ge 测试是否大于等于
&& or and 测试逻辑与
|| or or 测试逻辑或
! or not 测试取反
empty 测试是否空值

JSP EL隐含对象

(JSP九大隐式对象见https://www.zybuluo.com/nextleaf/note/1282797#jsp%E9%9A%90%E5%90%AB%E5%AF%B9%E8%B1%A1

隐含对象 描述
pageScope page 作用域
requestScope request 作用域
sessionScope session 作用域
applicationScope application 作用域
param Request 对象的参数,字符串
paramValues Request对象的参数,字符串集合
header HTTP 信息头,字符串
headerValues HTTP 信息头,字符串集合
initParam 上下文初始化参数
cookie Cookie值
pageContext 当前页面的pageContext
  1. <%@ page import="s.entity.User" %>
  2. <%@ page import="java.time.LocalDate" %>
  3. <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
  4. <html>
  5. <head>
  6. <title>a</title>
  7. </head>
  8. <body>
  9. <%request.setAttribute("user", new User("slf", "huang", LocalDate.now()));%>
  10. <div>${user.username}</div>
  11. <div>${user.password}</div>
  12. <div>${user.birthday}</div>
  13. <div>算术运算${"123"+"456"}</div>
  14. <div>算术运算${"123"+456}</div>
  15. <div>加号“+”不能用于字符串拼接<%--$报错{"123a"+456}--%></div>
  16. <div>逻辑运算</div>
  17. </body>
  18. </html>

Servlet上下文——ServletContext

ServletContext是JavaWeb四大域对象之一每个Web项目,运行时部署在Web应用服务器(如Tomcat)下,我们称之为一个应用(Application)。
一个Web应用里可以有多个Servlet,而这里的Servlet上下文就可以理解为这些Servlet的运行环境。

1、生命周期:

当Web应用被加载进容器时创建代表整个web应用的ServletContext对象,当Web应用被移除或服务器关闭时,ServletContext对象跟着销毁。

2、作用范围:整个Web应用。

3、作用:

a)在不同Servlet 之间转发    this.getServletContext().getRequestDispatcher("/servlet/Demo10Servlet").forward(request,response);

方法执行结束,service就会返回到服务器,再有服务器去调用目标servlet,其中request会重新创建,并将之前的request的数据拷贝进去。

b)读取资源文件。

1、由于相对路径默认相对的是java虚拟机启动的目录,所以我们直接写相对路径将会是相对于tomcat/bin目录,所以是拿不到资源的。如果写成绝对路径,当项目发布到其他环境时,绝对路径就错了。

2、为了解决这个问题ServletContext提供了:

  this.getServletContext().getRealPath("/1.properties"),给进一个资源的虚拟路径,将会返回该资源在当前环境下的真实路径。        

  this.getServletContext().getResourceAsStream("/1.properties"),给一个资源的虚拟路径返回到该资源真实路径的流。

3、当在非servlet下获取资源文件时,就没有ServletContext对象用了,此时只能用类加载器

    classLoader.getResourceAsStream("../../1.properties"),此方法利用类加载器直接将资源加载到内存中,有更新延迟的问题,以及如果文件太大,占用内存过大。

   classLoader.getResource("../1.properties").getPath(),直接返回资源的真实路径,没有更新延迟的问题。

获得


面试题

session(HttpSession类的实例)的工作原理

。。。

请说一下转发和重定向的区别:

重定向:客户端请求容器的资源A,A可以发回一个302状态码和一个location的消息头,客户端收到状态码后,立即向location指向位置发出请求。
转发:客户端请求服务器的资源A,A通知容器,由容器将控制器交给组件B继续完成后续的工作。

(1).地址栏的变化:重定向后,地址栏会发生变化,转发后地址栏不会发生变化。

(2).请求的资源:转发只能是应用内的资源,而重定向没有这个限制。
(3).转发过程中涉及到的组件共享同一对request和response,而重定向则不会。

(4).执行效率:
转发是一次请求一次响应,效率相对较高。
重定向发了多次请求,效率相对转发较低。

如何选择使用转发还是使用重定向?
转发:一件事还没有做完,需要其他组件继续做。(例如当查询这一件事中,如果有了数据为了显示则用转发)
重定向:一件事做完了,去做另外一件事.(例如,增加或删除一条员工后想显示数据则用重定向)


login.jsp

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>登录页</title>
  5. <style>
  6. td{
  7. text-align: center;
  8. }
  9. </style>
  10. </head>
  11. <body>
  12. <div align="center">
  13. <form action="login.action" method="post">
  14. <table>
  15. <tr>
  16. <td>
  17. <label for="user-name-label1">用户名 </label>
  18. </td>
  19. <td><input name="username" required="required" id="user-name-label1"></td>
  20. </tr>
  21. <tr>
  22. <td><label for="user-name-label2">密码 </label>
  23. </td>
  24. <td><input type="password" name="password" required="required" id="user-name-label2"></td>
  25. </tr>
  26. <tr>
  27. <td colspan="2"><input type="submit" value="登录"></td>
  28. </tr>
  29. </table>
  30. </form>
  31. </div>
  32. </body>
  33. </html>

index.jsp

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
  2. <%@ page import="s.entity.User,java.time.*" %>
  3. <html>
  4. <head>
  5. <title>主页</title>
  6. </head>
  7. <body>
  8. <%
  9. HttpSession s = request.getSession(false);
  10. if (!s.isNew() && s.getAttribute("user") != null) {
  11. User user = (User) s.getAttribute("user");
  12. MonthDay birth = MonthDay.from(user.getBirthday());
  13. MonthDay currbirth = MonthDay.from(LocalDate.now());
  14. String str;
  15. if (birth.equals(currbirth)) {
  16. str = "!今天(" + LocalDate.now().toString() +
  17. ")是你的生日(" + user.getBirthday() + ")";
  18. } else {
  19. str = "!今天(" + LocalDate.now().toString() +
  20. ")不是你的生日(" + user.getBirthday() + ")";
  21. }
  22. out.print("<!doctype html><html lang=\"zh\"><head><meta charset=\"UTF-8\"><title>首页</title></head><body><div align=\"center\"><h1>你好," +
  23. user.getUsername() + str + "</h1><p><a href=\"logout.action\">登出</a></p></div></body></html>");
  24. out.flush();
  25. out.close();
  26. } else {
  27. System.out.println("登录后才能访问!");
  28. out.print("<!doctype html><html lang=\"zh\"><head><script type=\"text/javascript\">alert(\"登录后才能访问!\");window.location.href=\"login.jsp\";</script></head><body></body></html>");
  29. out.flush();
  30. out.close();
  31. }
  32. %>
  33. </body>
  34. </html>

LoginAction.java

  1. package s.controler;
  2. import s.dao.UserDao;
  3. import s.entity.User;
  4. import javax.servlet.ServletException;
  5. import javax.servlet.http.HttpServlet;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. import javax.servlet.http.HttpSession;
  9. import java.io.IOException;
  10. import java.io.PrintWriter;
  11. /**
  12. * Created with IntelliJ IDEA 2018.
  13. *
  14. * session(HttpSession类的实例)与cookie相比较
  15. *
  16. * (1) session存在服务器端,比较安全。
  17. * (2) session存储的数据大小没有限制
  18. * (3) session中存储的数据类型没有限定,而cookie只能存储字符串。
  19. *
  20. * @author: 黄昭鸿
  21. * @date: 2018-09-19
  22. * Time: 10:55
  23. */
  24. public class LoginAction extends HttpServlet {
  25. @Override
  26. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  27. this.doPost(req, resp);
  28. }
  29. @Override
  30. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  31. req.setCharacterEncoding("utf-8");
  32. resp.setCharacterEncoding("utf-8");
  33. resp.setContentType("text/html;charset=UTF-8");
  34. String uri = req.getRequestURI();
  35. String reqName = uri.substring(uri.lastIndexOf('/') + 1, uri.lastIndexOf('.'));
  36. System.out.println("请求为" + reqName);
  37. UserDao userDao = new UserDao();
  38. switch (reqName) {
  39. case "login":
  40. User user = userDao.validateUser(req.getParameter("username").trim(), req.getParameter("password").trim());
  41. if (user != null) {
  42. req.getSession().setAttribute("user", user);
  43. resp.sendRedirect("index.jsp");
  44. } else {
  45. System.out.println("验证失败");
  46. PrintWriter pw = resp.getWriter();
  47. pw.println("<!doctype html><html lang=\"zh\"><head><script type=\"text/javascript\">alert(\"验证失败\");window.location.href=\"login.jsp\";</script></head><body></body></html>");
  48. //resp.sendRedirect("login.jsp");
  49. pw.flush();
  50. pw.close();
  51. }
  52. break;
  53. case "logout":
  54. HttpSession s = req.getSession(false);
  55. if (s == null || s.getAttribute("user") == null) {
  56. resp.sendRedirect("login.jsp");
  57. /* 或者
  58. PrintWriter pw = resp.getWriter();
  59. pw.println("<!doctype html><html lang=\"zh\"><head><script type=\"text/javascript\">alert(\"未登录\");window.location.href=\"login.jsp\";</script></head><body></body></html>");
  60. pw.flush();
  61. pw.close();*/
  62. } else if (s.getAttribute("user") != null) {
  63. s.invalidate();
  64. PrintWriter pw = resp.getWriter();
  65. pw.println("<!doctype html><html lang=\"zh\"><head><script type=\"text/javascript\">alert(\"已退出\");window.location.href=\"login.jsp\";</script></head><body></body></html>");
  66. pw.flush();
  67. pw.close();
  68. }
  69. break;
  70. default:
  71. System.out.println("未定义的操作:" + reqName);
  72. }
  73. }
  74. }

UserDao.java

  1. package s.dao;
  2. import s.entity.User;
  3. import s.util.DButil;
  4. import java.sql.Connection;
  5. import java.sql.PreparedStatement;
  6. import java.sql.ResultSet;
  7. import java.time.LocalDate;
  8. /**
  9. * Created with IntelliJ IDEA 2018.
  10. * Description:
  11. *
  12. * @author: 黄昭鸿
  13. * @date: 2018-09-19
  14. * Time: 10:57
  15. */
  16. public class UserDao {
  17. //validateUser
  18. public User validateUser(String username, String password) {
  19. Connection con = null;
  20. User user;
  21. try {
  22. con = DButil.getConnection();
  23. String sql = "SELECT birthday FROM user WHERE username=? AND password=?";
  24. PreparedStatement ps = con.prepareStatement(sql);
  25. ps.setString(1, username);
  26. ps.setString(2, password);
  27. ResultSet rs = ps.executeQuery();
  28. //SQLException: Before start of result set
  29. //在对结果集ResultSet进行操作之前,一定要先用ResultSet.next()将指针移动至结果集的第一行
  30. if (rs.next()) {
  31. user = new User(username,password, LocalDate.parse(rs.getString("birthday")));
  32. System.out.println(username+"验证成功");
  33. return user;
  34. }else {
  35. System.out.println("用户名或密码错误");
  36. return null;
  37. }
  38. } catch (Exception e) {
  39. e.printStackTrace();
  40. return null;
  41. } finally {
  42. if (con != null) {
  43. DButil.closeConnection(con);
  44. }
  45. }
  46. }
  47. //返回user或null
  48. public User findById(String id) {
  49. Connection con = null;
  50. User user = null;
  51. try {
  52. con = DButil.getConnection();
  53. String sql = "SELECT username,password,birthday FROM user WHERE username=?";
  54. PreparedStatement ps = con.prepareStatement(sql);
  55. ps.setString(1, id);
  56. ResultSet rs = ps.executeQuery();
  57. //SQLException: Before start of result set
  58. //在对结果集ResultSet进行操作之前,一定要先用ResultSet.next()将指针移动至结果集的第一行
  59. if (rs.next()) {
  60. user = new User(rs.getString("username"), rs.getString("password"), LocalDate.parse(rs.getString("birthday")));
  61. System.out.println(rs.getString("birthday"));
  62. }
  63. return user;
  64. } catch (Exception e) {
  65. e.printStackTrace();
  66. return null;
  67. } finally {
  68. if (con != null) {
  69. DButil.closeConnection(con);
  70. }
  71. }
  72. }
  73. }

User.java

  1. package s.entity;
  2. import java.time.LocalDate;
  3. /**
  4. * Created with IntelliJ IDEA 2018.
  5. * Description:实体类
  6. * API版本在1.8+才能使用LocalDate类
  7. *
  8. * @author: 黄昭鸿
  9. * @date: 2018-09-19
  10. * Time: 10:58
  11. */
  12. public class User {
  13. private String username,password;
  14. //mysql不支持Date类型设置默认值
  15. private LocalDate birthday;
  16. public User() {
  17. }
  18. public User(String username, String password, LocalDate birthday) {
  19. this.username = username;
  20. this.password = password;
  21. this.birthday = birthday;
  22. }
  23. @Override
  24. public String toString() {
  25. return "User{" +
  26. "username='" + username + '\'' +
  27. ", password='" + password + '\'' +
  28. ", birthday=" + birthday +
  29. '}';
  30. }
  31. public String getUsername() {
  32. return username;
  33. }
  34. public void setUsername(String username) {
  35. this.username = username;
  36. }
  37. public String getPassword() {
  38. return password;
  39. }
  40. public void setPassword(String password) {
  41. this.password = password;
  42. }
  43. public LocalDate getBirthday() {
  44. return birthday;
  45. }
  46. public void setBirthday(LocalDate birthday) {
  47. this.birthday = birthday;
  48. }
  49. }

web.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
  5. version="4.0">
  6. <welcome-file-list>
  7. <welcome-file>login.jsp</welcome-file>
  8. </welcome-file-list>
  9. <servlet>
  10. <servlet-name>loginAction</servlet-name>
  11. <servlet-class>s.controler.LoginAction</servlet-class>
  12. </servlet>
  13. <servlet-mapping>
  14. <servlet-name>loginAction</servlet-name>
  15. <url-pattern>*.action</url-pattern>
  16. </servlet-mapping>
  17. </web-app>
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注