一:会话技术概述
1.概述:会话就是由多次请求和响应组成的一次网络上的活动;
2.会话过程中要解决的问题:多次请求和响应之间需要存储数据;
3.会话期间存储数据的技术:会话技术
①:Cookie:将数据存储在浏览器端
②:Session:将数据存储在服务器端
4.会话技术存储数据的特点:在多次请求和响应之间共享
二:Cookie技术
1.概述:Cookie指的是少量信息;
2.Cookie的产生:
①:创建:由web服务器创建,并发送给浏览器;
②:保存:保存在浏览器端(硬盘上);
3.应用场景:
①:自动登录;
②:记住登录用户名和密码信息;
4.Cookie基本API:
创建: Cookie cookie = new Cookie(name,value);
获取name值: String name = cookie.getName();
获取value值: Strign value = cookie.getValue();
发送cookie: response.addCookie(cookie);
设置cookie的值: cookie.setValue(value);
获取所有cookie: Cookie[] getCookies() = rquest.getCookies();
5.Cookie的存活时间:
①:我们创建的Cookie对象默认是会话级别的Cookie,浏览器关闭后Cookie立即销毁;
②:持久型的Cookie:浏览器关闭后能够保存一段时间,设置Cookie的最大存活时间:cookie.setMaxAge(int second);
6.Cookie的有效路径:
①:Cookie能够被访问到的路径;
②:能够在有效路径或其子路径下获取到Cookie;
③:通常设置Cookie的有效路径为"/"或不设置;
7.Cookie删除:
①:客户端:
- 会话级别的cookie,关闭浏览器后cookie立即消失;
- 禁用cookie;
- 手动清除cookie;
②:服务端: - 通过Servlet,将原来的cookie置换;
8.Cookie的优势及弊端: - 优势:
- 为服务端标识用户提供依据;
- 减轻了服务端数据存储的压力;
- 弊端:
- 数据存储在客户端不安全;
- 存储的数据大小受限,一个cookie存储的数据最大为4K;
案例:记住用户名和密码案例(自己实现过)
<script>
//页面加载完成之后 从浏览器中获取Cookie
$(function () {
var name = cookie.getCookie("name");
var password = cookie.getCookie("password");
//将用户名和密码更新到文本框中
$("#inputName").val(name ? name : "");
$("#inputPassword").val(password ? password : "");
//恢复记住我复选框的状态
if(name && password) {
$("#rememberMe").prop("checked","checked");
}
});
</script>
上述js代码中:cookie.getCookie()方法被封装在common.js中,使用前,先导入common.js文件。
var cookie = {
getCookie: function (key) {
return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(key).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
}
};
第一步:用户登录成功之后,获取用户的用户名和密码;
第二步:创建Cookie对象,保存用户的用户名和密码信息;
第三步:将Cookie发送给浏览器保存;
//3、响应数据
if (loginFlag) {
//如果记住我复选框被勾选
if ("remember-me".equals(rememberMe)) {
//处理记住密码业务逻辑
Cookie nameCookie = new Cookie("name", name);
Cookie pwdCookie = new Cookie("password", password);
//将Cookie发送给浏览器
response.addCookie(nameCookie);
response.addCookie(pwdCookie);
}
//登录成功 重定向到成功页面
response.sendRedirect("/success.html");
}
三:session技术
1.概念:Session是服务器为每个访问这个服务器的客户端用户创建的一个容器。
2.作用:这个容器中存储的数据能够在多个request之间实现共享。
3.特点:服务器为每个访问这个服务器的客户端用户创建的一个容器。
4.Session最常见的应用场景:
①:登录成功之后,将用户数据保存在session中;
②:验证码校验过程中,将服务器端生成的验证码保存在session中;
5.Session常用API(重要)
6.Session标识用户的原理:
第一步:第一次创建session对象时,服务器把sessionid以Cookie的形式发送给浏览器;
第二步:浏览器第二次访问服务器的时候,会携带这个Cookie;
第三步:服务器根据浏览器上次存储在Cookie中的sessionId,查找到上次的Session;
7.Session的生命周期
①:创建时机:第一次调用reqeust.getSession(); tomcat创建
②:使用session:域对象
作用:存储数据 API: setAttribute(name,value) getAttribute(name)
特点:在服务器端共享数据(多次请求和响应之间)
③:销毁:
1、session手动销毁:session.invilidate();
2、过期销毁:session默认存活时间–30min
3、非正常关闭tomcat;
8.浏览器关闭后,session持久化方案:
①. 在Servlet中手动创建JESSIONID;
②. 手动设置JESSIONID的存活时间;
③. 将JESSIONID相应给浏览器;
9.Session综合案例(验证码校验)
①:页面
<form class="form-signin" action="/loginServlet" method="post">
<div class="text-center">
<h2 class="form-signin-heading">登录页面</h2>
</div>
<input type="text" name="name" id="inputName" class="form-control" placeholder="用户名" required autofocus>
<input type="password" name="password" id="inputPassword" class="form-control" placeholder="密码" required>
<div>
<input type="text" name="checkCode" class="form-control" style="width: 184px;float: left;" placeholder="请输入验证码">
<img style="width: 84px;margin-left: 29px;" src="/checkCodeServlet" alt="">
</div>
<div class="checkbox" style="clear: both">
<label>
<input type="checkbox" id="rememberMe" name="rememberMe" value="remember-me"> 记住我
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit">登录</button>
</form>
②:CheckCodeServlet
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
/**
*
*/
@WebServlet("/CheckCodeServlet")
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 {
// gui 生成图片
// 1 高和宽
int height = 30;
int width = 60;
String data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
Random random = new Random();
// 2 创建一个图片
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 3 获得画板
Graphics g = image.getGraphics();
// 4 填充一个矩形
// * 设置颜色
g.setColor(Color.BLACK);
g.fillRect(0, 0, width, height);
g.setColor(Color.WHITE);
g.fillRect(1, 1, width - 2, height - 2);
// * 设置字体
g.setFont(new Font("宋体", Font.BOLD | Font.ITALIC, 25));
StringBuffer sb = new StringBuffer();
// 5 写随机字
for (int i = 0; i < 4; i++) {
// 设置颜色--随机数
g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
// 获得随机字
int index = random.nextInt(data.length());
String str = data.substring(index, index + 1);
// 写入
g.drawString(str, width / 6 * (i + 1), 20);
sb.append(str);// 获取验证码数据
}
// 验证码保存到session中
request.getSession().setAttribute("code",sb.toString());
// 6 干扰线
for (int i = 0; i < 3; i++) {
// 设置颜色--随机数
g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
// 随机绘制先
g.drawLine(random.nextInt(width), random.nextInt(height), random.nextInt(width), random.nextInt(height));
// 随机点
g.drawOval(random.nextInt(width), random.nextInt(height), 2, 2);
}
// end 将图片响应给浏览器
ImageIO.write(image, "jpg", response.getOutputStream());
}
}
③:LoginServlet
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
*@author hzj
*/
@WebServlet("/loginServlet")
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");
//1、获取请求数据
String name = request.getParameter("name");
String password = request.getParameter("password");
String rememberMe = request.getParameter("rememberMe");
//获取验证码
String checkCode = request.getParameter("checkCode");
//封装数据
User user = new User();
user.setName(name);
user.setPassword(password);
//验证码校验
//1、获取session中的验证
String serverCode = (String) request.getSession().getAttribute("code");
if(!serverCode.equalsIgnoreCase(checkCode)){
//验证码错误
//登录失败 拼接login.html,并回显错误信息
request.setAttribute("errorMsg", "验证码错误!");
request.getRequestDispatcher("/loginErrorServlet").forward(request, response);
return;
}
//2、处理数据:登录业务逻辑
UserService userService = new UserService();
boolean loginFlag = userService.login(user);
//3、响应数据
if (loginFlag) {
//如果记住我复选框被勾选
if ("remember-me".equals(rememberMe)) {
//处理记住密码业务逻辑
Cookie nameCookie = new Cookie("name", name);
Cookie pwdCookie = new Cookie("password", password);
//将Cookie发送给浏览器
response.addCookie(nameCookie);
response.addCookie(pwdCookie);
}
//登录成功 重定向到成功页面
response.sendRedirect("/success.html");
} else {
//登录失败 拼接login.html,并回显错误信息
request.setAttribute("errorMsg", "用户名或密码错误!");
request.getRequestDispatcher("/loginErrorServlet").forward(request, response);
}
}
}