会话的概念:用户打开浏览器,浏览不同的网页(资源),发出多个请求,直到关闭浏览器的过程,称为一次会话(多次请求)。即浏览器从开启到关闭,中间的使用过程。
会话技术:在会话过程(多次请求)中,用户产生的一些数据需要通过会话技术保存起来。会话技术可以保存用户各自(以浏览器为单位)的数据。
一、Cookie
1. 概念
原理:cookie是客户端(浏览器)端的技术,用户浏览的信息以键值对(key-value)的形式保存到浏览器上。若未关闭浏览器,就会将cookie数据带到服务端,服务端可以通过接口来获取cookie数据
作用
使用场景
- 浏览器记住用户名和密码,下次自动登录
- 保存电影的播放进度
2. 使用方式
2.1 API
-
创建Cookie:cookie的数据只能是键值对,且长度有限制;value中不能有空格 new Cookie(String name,String value);
-
设置cookie生命周期:0代表废除当前cookie,非0即便关掉浏览器依然有效 cookie.setMaxAge(int expiry);
-
设置cookie路径:用来区别不同服务端的数据,一般为request.getContextPath() cookie.setPath(String url);
-
将cookie回复浏览器:将cookie数据返回给客户端,本质上是响应头 response.addCookie(cookie);
-
获取所有cookie:所有cookie是以数组的方式呈现,本质上是请求头 request.getCookies();
-
获取cookie的值 cookie.getName();
cookie.getValue();
2.2 使用
封装工具类
public class ServletUtils {
public static Cookie getCookie(String name, String value, int maxAge, String path) {
Cookie cookie = new Cookie(name, value);
if (null != cookie) {
cookie.setMaxAge(maxAge);
cookie.setPath(path);
return cookie;
}
return null;
}
public static String getCookieValue(Cookie[] cookies, String name) {
if (null != cookies) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals(name)) {
return cookie.getValue();
}
}
}
return null;
}
}
3. 实例:获取上次访问时间
@WebServlet("/lasttime")
public class GetLastTime extends HttpServlet {
...
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
String lasttime = ServletUtils.getCookieValue(request.getCookies(), "lasttime");
System.out.println(lasttime);
if (lasttime == null) {
response.getWriter().println("第一次访问");
} else {
response.getWriter().println("上次访问时间:" + lasttime);
}
String date = new SimpleDateFormat("yyyy-MM-dd/HH:mm:ss").format(new Date());
Cookie cookie = ServletUtils.getCookie("lasttime", date, 60*60, request.getContextPath());
response.addCookie(cookie);
}
}
二、Session
1. 概念
1.1 基本介绍
概述
session是服务器端的技术,服务器为每一个浏览器开辟一块内存空间,即session对象。
- 每个浏览器在服务器中中都有一个特有的session对象,所以用户记录可以存放在session对象中
- 每一个session对象都对应一个存放在cookie中的sessionId,服务器通过浏览器带过来的sessionId找到对应的session对象
执行原理
-
获取浏览器请求中cookie中的sessionid -
若无sessionid,则创建session对象,并将sessionid通过cookie存入浏览器 -
若有sessionid,则通过sessionid找到对应的session对象后使用
关闭浏览器和服务器
-
关闭浏览器
- 关闭浏览器不代表其在服务器对应的session就销毁了,而是浏览器通过cookie保存的sessionid销毁了,无法通过sessionid找到对应的session了。
- 若要长期使用session,可以通过设置sessionid的cookie(
JSESSIONID )声明周期的方式来实现。 -
关闭服务器
- 如果是正常关闭服务器,把session钝化到服务器磁盘上,再次启动,把磁盘上的文件活化到内存里
- Session钝化:把内存中的session序列化保存到硬盘上
- Session活化:从硬盘上读取序列化的session到内存中形成一个session对象
1.2 对比
cookie和session
- cookie是保存在浏览器端,大小和个数都有限制;session是保存在服务器端的, 原则上大小是没有限制
- cookie不支持中文,并且只能存储字符串;session可以存储基本数据类型,集合,对象等
三个域对象比较
域对象 | 创建 | 销毁 | 作用范围 | 应用场景 |
---|
ServletContext | 服务器启动 | 服务器正常关闭/项目从服务器移除 | 整个项目 | 记录网站访问次数,聊天室 | HttpSession | 没有JSESSIONID这个cookie的时候,调 用request.getSession()方法 | session过期(默认闲置30分钟),或者调用session对象的invalidate()方法,或者服务器异常关闭 | 会话(多次请求) | 验证码校验, 保存用户登录状态等 | HttpServletRequest | 来了请求 | 响应这个请求(或者请求已经接收了) | 一次请求 | servletA和jsp(servletB)之间数据传递(转发的时候存数据) |
域对象的选择
- 一般情况下, 最小的可以解决就用最小的
- 根据情况,如重定向, 多次请求, 会话范围, 用session; 如果是转发,一般选择request
- 若必须要存在浏览器上的数据(如用户名、登录密码等用户信息)用cookie,否则一般都是用session
2. 使用方式
2.1 API
获取session,第一次使用实际上是创建session
request.getSession();
设置session数据
Object getAttribute(String name);
获取session数据
void setAttribute(String name, Object value);
移除当前session
void removeAttribute(String name);
2.2 使用
SessionServletDemo01.class
@WebServlet("/session01")
public class SessionServletDemo01 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
String str = "jay";
session.setAttribute("str", str);
}
}
SessionServletDemo02.class
@WebServlet("/session02")
public class SessionServletDemo02 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
String str = (String) session.getAttribute("str");
System.out.println(str);
}
}
3. 实例:验证码校验
CheckCodeServlet.class
@WebServlet("/checkCode")
public class CheckCodeServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ValidateCode validateCode = new ValidateCode(120, 40, 5, 100);
validateCode.write(response.getOutputStream());
HttpSession session = request.getSession();
String code = validateCode.getCode();
session.setAttribute("ValidateCode", code);
}
}
LoginServlet.class
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
String checkCode = request.getParameter("checkCode");
HttpSession session = request.getSession();
String code = (String) session.getAttribute("ValidateCode");
if (code.equalsIgnoreCase(checkCode)) {
sout("验证码正确");
}
}
}
三、JSP
1. 概述
JSP(Java Server Page):java服务器页面,JSP本质就是servlet,用于开发动态web资源的技术。包含html(js、css) + java(servlet) + jsp(内置对象、子陵、动作标签等)特有内容
作用
当服务器用servlet通过getWrite().write() 方法,向html展示页面输出一个动态的表格等动态资源时,步骤会相当繁琐。为了解决这个问题,定义了JSP,其文件内部可以同时写HTML和JAVA代码
执行原理
JSP会通过默认的JspServlet、JSP引擎翻译成Servlet的.java 文件,将Servlet的.java 文件编译成.class 文件。所以.jsp文件本质上还是servlet文件,最终还是用转换后的servlet文件通过getWrite().write() 方式向html输出html文本。
- 第一次访问的jsp文件时,服务器会通过JspServlet去查找对应的jsp文件
- 找到之后,服务器会将这个jsp文件转换成.java文件(Servlet)
- 服务器编译java文件,生成class文件
- 服务器运行class文件,生成动态的内容
- 服务器收到内容之后,返回给浏览器
**
2. 基本语法
2.1 语法
脚本
类型 | 翻译成Servlet对应的部分 |
---|
<%…%>:Java程序片段 | 翻译成Service() 方法里面的内容, 局部的 | <%=…%>:输出表达式 | 翻译成Service() 方法里面的内容,相当于调用out.print() | <%!..%>:声明成员变量(肯定不用) | 翻译成Servlet 类里面的内容 |
注释
| 注释类型 |
---|
| HTML注释 | // 或 /* */ | JAVA注释 | <%–注释内容–%> | JSP注释 |
2.2 使用
test.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登陆页面</title>
</head>
<body>
<%--JAVA代码--%>
<%
//获取cookie
String username = "";
for (int i = 0; i < 10; i++) {
sout("i");
}
%>
<%--HTML文本-%>
<form action="login" method="post">
<!--用户名-->
用户名<input type="text" name="username" value=<%=username%>><br>
密码<input type="password" name="password"><br>
</form>
</body>
</html>
3. 实例:优化登录案例
login.jsp:
- 根据登录时不同的错误错误,输出不同的错误提醒
- 根据点击/取消保存用户名,实现用户名输入栏自动出现/消失用户名
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登陆页面</title>
</head>
<body>
<%--获取错误码--%>
<%
String errMsg = (String) request.getAttribute("errMsg");
if (errMsg == null) {
errMsg = "";
}
//获取cookie
String username = "";
String remember = "";
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
if (cookie.getName().equals("username")) {
username = cookie.getValue();
remember = "on";
System.out.println(username);
}
}
%>
<div style="color: red"><%=errMsg%></div><br>
<form action="login" method="post">
用户名<input type="text" name="username" value=<%=username%>><br>
密码<input type="password" name="password"><br>
验证码<input type="text" name="checkCode"><br>
<img src="checkCode" width="200"><br>
<input type="checkbox" name="remember" value=<%=remember%>记住用户名<br>
<input type="submit" value="提交">
</form>
</body>
</html>
LoginServlet.java
- 校验浏览器发送的登录数据不对时,跳转回登录页面
- 保存当前会话的用户数据
- 根据浏览器的选择,将用户名发送/取消给浏览器
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
String checkCode = request.getParameter("checkCode");
String remember = request.getParameter("remember");
Cookie cookie = new Cookie("username", username);
cookie.setPath(request.getContextPath());
if (remember != null) {
cookie.setMaxAge(60*60*24);
System.out.println(username);
} else {
cookie.setMaxAge(0);
}
response.addCookie(cookie);
HttpSession session = request.getSession();
String code = (String) session.getAttribute("ValidateCode");
if (code.equalsIgnoreCase(checkCode)) {
String sql = "select * from user where username=? and password=?";
QueryRunner queryRunner = new QueryRunner(DruidUtil.getDataSource());
try {
User user = queryRunner.query(sql, new BeanHandler<>(User.class), username, password);
if (user != null) {
response.getWriter().write("登录成功");
session.setAttribute("user", user);
request.getRequestDispatcher("success.jsp").forward(request, response);
}else {
String errMsg = "用户名或密码错误";
request.setAttribute("errMsg", errMsg);
request.getRequestDispatcher("login.jsp").forward(request, response);
}
} catch (Exception e) {
e.printStackTrace();
String errMsg = "用户名或密码错误";
request.setAttribute("errMsg", errMsg);
request.getRequestDispatcher("login.jsp").forward(request, response);
}
} else {
String errMsg = "验证码错误";
request.setAttribute("errMsg", errMsg);
request.getRequestDispatcher("login.jsp").forward(request, response);
}
}
}
|