会话
常用的会话技术
Cookie
是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源事务,就会带着自己的数据去。这样,web资源处理的就是用户各自的数据了
Session
是服务端的技术,服务器为每个浏览器开辟一块内存空间,即session。由于内存空间是每一个浏览器独享的,所有用户访问的时候,可以把信息保存在session对象中。同时,每一个session对象对应一个sessionid,服务器把sessionid写到cookie中,再次访问的时候,浏览器会把cookie带过来,找到对应的对象
Cookie
是一种客户端的会话技术,它是服务器存放在浏览器的一小份数据,浏览器以后每次访问该服务器的时候都会将这小份数据携带到服务器去
作用
在浏览器中存放数据
将浏览器中存放的数据携带到服务器
相关API
//创建一个cookie对象
new Cookie(String name,String value);
//将cookie写回浏览器
response.addCookie(cookie);
//获得浏览器带过来的cookie
request.getCookies();
//返回cookie中设置的key
cookie.getName();
//返回cookie中设置的value
cookie.getValue();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie[] cookies = request.getCookies();
if (cookies != null){
for (Cookie cookie : cookies) {
if ("akey".equals(cookie.getName())){
System.out.println(cookie.getValue());
}
}
}
Cookie cookie = new Cookie("akey","aaa");
response.addCookie(cookie);
}
一般把cookie封装起来
public class CookieUtils {
public static Cookie getTargetCookie(String key,Cookie[] cookies){
if (cookies == null){
return null;
}
for (Cookie cookie : cookies) {
if (key.equals(cookie.getName())){
return cookie;
}
}
return null;
}
}
cookie分类
会话级别cookie
默认情况下,当浏览器进程结束的时候,cookie就会消失
持久性cookie
给cookie设置有效期
cookie.setMaxAge(int expiry);
-1:默认,代表数据存到浏览器关闭,保存在浏览器文件中
0:代表删除cookie,如果要删除cookie要确保路径一致
大于0:以秒为单位保存数据有效时间(把缓存数据保存到磁盘中)
cookie设置有效路径
setPath(String url)
作用
保证不会携带别的网站 / 项目里面的cookie到我们自己的项目
如果路径不一样,cookie的key可以调用
保证自己的项目可以合理的利用自己项目的cookie
默认路径
随带cookie需要的条件:只有当访问资源的url包含此cookie的有效path的时候,才会携带这个cookie
cookie路径一般这么设置:
cookie.setPath(request.getContextPath());
案例-记录用户各自的上次访问时间
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
Cookie[] cookies = request.getCookies();
Cookie targetCookie = CookieUtils.getTargetCookie("lasttime",cookies);
if (targetCookie == null){
Cookie cookie = new Cookie("lasttime",System.currentTimeMillis() + "");
cookie.setMaxAge(60*60);
cookie.setPath(request.getContextPath());
response.addCookie(cookie);
response.getWriter().print("第一次访问");
}
else {
// Cookie cookie = new Cookie("lasttime",System.currentTimeMillis()+"");
// cookie.setPath(request.getContextPath());
// cookie.setMaxAge(60*60);
// response.addCookie(cookie);
String time = targetCookie.getValue();
Date date = new Date(Long.parseLong(time));
response.getWriter().print("你上次访问的事件是" + date.toLocaleString());
}
}
Session
是服务器端技术。服务器为每一个浏览器开辟一块内存空间,即session对象
cookie和session的不同
cookie是保存在浏览器端的,大小和个数都有限制。session保存在服务器端,原则上大小没有限制,安全一些
cookie不支持中文,并且只能存储字符串;session可以存储基本数据类型,集合,对象等
执行流程
获得cookie中传递过来的sessionId(cookie)
如果Cookie中没有sessionId,则创建session对象
如果Cookie中有sessionId,找指定的session对象
如果有sessionId并且session对象存在,则直接使用
如果有sessionId,但session对象销毁了,则执行第二步
session基于cookie
范围
会话,以浏览器为单位保存用户各自的数据
request.getSession();
Object getAttribute(String name):获取值
void setAttribute(String name,Object value); 存储值
void removeAttribute(String name); 移除
三个域对象比较
ServletContext
HttpSession
HttpServletRequest
如果是正常关闭服务器
把session钝化到服务器磁盘上,再次启动,把磁盘上的文件活化到内存里面
三个域对象怎么选择
一般情况下,最小的可以解决就用最小的
重定向,多次请求,会话范围,用
session
如果是转发,一般选择request
案例:一次性验证码校验
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<center>
<h1>用户登录:</h1>
<form action="login" method="post">
姓名:<input type="text" name="username"/><br/>
密码:<input type="password" name="password"/><br/>
验证码:<input type="text" name="code"/><br/>
<img src="code" onclick="changeImg(this)"/><br/>
<input type="submit" value="登录">
</form>
</center>
</body>
</html>
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.io.IOException;
@WebServlet("/login")
public class LoginServlet 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 {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset = utf-8");
String usercode = request.getParameter("code");
String code = (String) request.getSession().getAttribute("code");
if (!code.equals(usercode)){
response.getWriter().print("验证码有误");
return;
}
}
}
import cn.dsna.util.images.ValidateCode;
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.io.IOException;
@WebServlet("/code")
public class CodeServlet 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(200,50,4,100);
String code = validateCode.getCode();
System.out.println(code);
request.getSession().setAttribute("code",code);
validateCode.write(response.getOutputStream());
}
}