Cookie与Session
# 1.cookie
1.会话概述
产生问题:
解决:
2.CookieAPI介绍
3.Cookie属性
1.获取客户端Cookied最后一次访问的时间,响应给客户端时更新最后一次访问时间
package com.xu.cookieAndsession;
import javafx.scene.chart.PieChart;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.io.IOException;
import java.util.Calendar;
/**
* @auther xu
* @date 2022/4/11 - 3:38
*/
public class CookieDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建一个输出流对象
PrintWriter out= null;
try {
//指定服务器端解码方式
resp.setCharacterEncoding("UTF-8");
out = resp.getWriter();
//获取客户端Cookied最后一次访问的时间
//1.获取该cookie数组(一个服务器在客户端缓存中最多保存20个Cookie)
Cookie[] cookies = req.getCookies();
//2.遍历cookie数组
for (int i = 0; cookies != null && i < cookies.length; i++) {//客户端第一次访问服务器时request对象中不会携带Cookie
if ("lastAccessTime".equals((cookies[i].getName()))) {
String value = cookies[i].getValue();
//2.将得到的时间格式化
long l = Long.parseLong(value);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String format = simpleDateFormat.format(l);
//3.响应给客户端
out.write(format);
}
}
//4.创建cookie对象
Cookie lastAccessTime = new Cookie("lastAccessTime", System.currentTimeMillis() + "");
//5.将Cookie响应给客户端,更新客户端缓存
resp.addCookie(lastAccessTime);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (out != null) {
out.close();
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
}
输出结果:
2.浏览器一关闭,内存释放了,Cookie会话结束,如上,服务器不关闭,关闭浏览器,再访问同一个地址,不会出现时间
3.将Cookie数据持久化---存到硬盘(设置)
实现:
输出结果:
补充:应该不会加一秒,如果速度够块,是不会加1秒的
4.路径名决定是否带Cookie
CookieDemo1代码与CookieDemo2一致:
package com.xu.cookieAndsession;
import javafx.scene.chart.PieChart;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.io.IOException;
import java.util.Calendar;
/**
* @auther xu
* @date 2022/4/11 - 3:38
*/
public class CookieDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建一个输出流对象
PrintWriter out= null;
try {
//指定服务器端解码方式
resp.setCharacterEncoding("UTF-8");
out = resp.getWriter();
//获取客户端Cookied最后一次访问的时间
//1.获取该cookie数组(一个服务器在客户端缓存中最多保存20个Cookie)
Cookie[] cookies = req.getCookies();
//2.遍历cookie数组
for (int i = 0; cookies != null && i < cookies.length; i++) {//客户端第一次访问服务器时request对象中不会携带Cookie
if ("lastAccessTime".equals((cookies[i].getName()))) {
String value = cookies[i].getValue();
//2.将得到的时间格式化
long l = Long.parseLong(value);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String format = simpleDateFormat.format(l);
//3.响应给客户端
out.write(format);
}
}
//4.创建cookie对象
Cookie lastAccessTime = new Cookie("lastAccessTime", System.currentTimeMillis() + "");
//4-1:设置Cookie的有效时间为(以秒为单位)
lastAccessTime.setMaxAge(60*5);//设置cookie的保存时间为5分钟
//5.将Cookie响应给客户端,更新客户端缓存
resp.addCookie(lastAccessTime);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (out != null) {
out.close();
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
}
该种路径也行(也会携带cookie):
1.调用方法设置path,只要在该路径下访问Servlet页面,浏览器都需要携带cookie
补充反例:
5.cookie存入中文时,需要使用的编码与解码
6.删除cookie
通过在CookieClearnDemo类创建cookie对象,并将setMaxAge(0),设置为0,相当于删除Cookie,响应给客户端,更新cookie
CookieClearnDemo类:
package com.xu.cookieAndsession;
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;
/**
* @auther xu
* @date 2022/4/11 - 13:49
*/
public class CookieClearnDemo extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//创建一个Cookie
Cookie ck = new Cookie("lastAccessTime", "");
//明确删除那一条路径下的cookie,"/"代表删除"/secondServlet"路径下的所有cookie
ck.setPath("/");
ck.setMaxAge(0);//设置为0,相当于删除Cookie
response.addCookie(ck);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
CookieDemo1与CookieDemo2代码一样:
package com.xu.cookieAndsession;
import javafx.scene.chart.PieChart;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//import javax.xml.crypto.Data;
import java.io.PrintWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.io.IOException;
import java.util.Calendar;
/**
* @auther xu
* @date 2022/4/11 - 3:38
*/
public class CookieDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建一个输出流对象
PrintWriter out= null;
try {
//指定服务器端解码方式
resp.setCharacterEncoding("UTF-8");
out = resp.getWriter();
//获取客户端Cookied最后一次访问的时间
//1.获取该cookie数组(一个服务器在客户端缓存中最多保存20个Cookie)
Cookie[] cookies = req.getCookies();
//2.遍历cookie数组
for (int i = 0; cookies != null && i < cookies.length; i++) {//客户端第一次访问服务器时request对象中不会携带Cookie
if ("lastAccessTime".equals((cookies[i].getName()))) {
String value = cookies[i].getValue();
//2.将得到的时间格式化
long l = Long.parseLong(value);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String format = simpleDateFormat.format(l);
//3.响应给客户端
out.write(format);
}
}
//4.创建cookie对象
Cookie lastAccessTime = new Cookie("lastAccessTime", System.currentTimeMillis() + "");
//4-1:设置Cookie的有效时间为(以秒为单位)
lastAccessTime.setMaxAge(60*5);//设置cookie的保存时间为5分钟
//4-2:调用方法设置path,只要在该路径下访问Servlet页面,浏览器都需要携带cookie
// lastAccessTime.setPath("/secondServlet");
// lastAccessTime.setPath(req.getContextPath());
lastAccessTime.setPath("/");
//5.将Cookie响应给客户端,更新客户端缓存
resp.addCookie(lastAccessTime);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (out != null) {
out.close();
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
}
xml:
4.记住用户名
xml:
loginServlet.java:
package com.xu.test;
import com.sun.xml.internal.ws.transport.http.HttpAdapter;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @auther xu
* @date 2022/4/11 - 19:01
*/
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
String userName = "";
String checked = "";
//得到客户端保存的Cookie数据
Cookie[] cookies = req.getCookies();
for (int i = 0;cookies != null && i < cookies.length; i++) {
if ((cookies[i].getName()).equals("userName")) {
userName = cookies[i].getValue();
checked = "checked='checked'";
}
}
out.write("<form action='"+req.getContextPath()+"/servlet/doLogin' method='post'>");
out.write("用户名:<input type='text' name='userName' value='"+userName+"'/><br/>");
out.write("密码:<input type='password' name='pwd'/><br/>");
out.write("记住用户名:<input type='checkbox' name='remember' "+checked+"/><br/>");//如果cookie有数据,就会自动记住用户名
out.write("<input type='submit' value='登录'/><br/>");
out.write("</form>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
}
doLoginServlet.java:
package com.xu.test;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @auther xu
* @date 2022/4/11 - 21:17
*/
public class DoLoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//保证编码,解码一致性
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
//1.获取表单数据
String userName = req.getParameter("userName");
String password = req.getParameter("pwd");
String remember = req.getParameter("remember");
Cookie ck= new Cookie("userName", userName);//创建cookie对象
ck.setPath("/");//设置在当前应用下操作cookie
//2.处理业务逻辑
//3.分发转向
if ("Tom".equals(userName) && "123".equals(password)) {
if (remember != null) {
ck.setMaxAge(Integer.MAX_VALUE);//相当将cookie永久保存
} else {
ck.setMaxAge(0);//将cookie删除
}
resp.addCookie(ck);//将cookie响应给客户端
out.write("登录成功!");
} else {
out.write("登录失败!");
resp.setHeader("refresh","2;url="+req.getContextPath()+"/servlet/login");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
}
操作结果:
关闭浏览器,再一次登录
再一次登录,因为没有cookie,所以userName,checked不会自动填充
5.历史记录思路分析:(没太听懂)
6.历史记录的实现
Book.java:
package com.xu.entity;
/**
* @auther xu
* @date 2022/4/12 - 6:45
*/
public class Book {
private String id;
private String name;
private int price;
private String anthor;
public Book(String id, String name, int price, String anthor) {
this.id = id;
this.name = name;
this.price = price;
this.anthor = anthor;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getAnthor() {
return anthor;
}
public void setAnthor(String anthor) {
this.anthor = anthor;
}
@Override
public String toString() {
return "Book{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", price=" + price +
", anthor='" + anthor + '\'' +
'}';
}
}
DButil.java:
package com.xu.util;
import com.xu.entity.Book;
import java.util.HashMap;
import java.util.Map;
/**
* @auther xu
* @date 2022/4/12 - 6:55
*/
public class DButil {
private static Map<String, Book> books = new HashMap<>();
static {
books.put("1",new Book("1","三国演义",30,"罗贯中"));
books.put("2",new Book("1","红楼梦",40,"曹雪芹"));
books.put("3",new Book("1","水浒传",30,"施耐庵"));
books.put("4",new Book("1","西游记",30,"吴承恩"));
}
//得到所有书的map集合
public static Map<String,Book> findAllBooks() {
return books;
}
/**
* 根据id查找指定的书
* @param id
* @return
*/
public static Book findBookById(String id) {
return books.get(id);
}
}
ShowAllBooksServlet.java:
package com.xu.history;
import com.xu.entity.Book;
import com.xu.util.DButil;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
/**
* @auther xu
* @date 2022/4/12 - 7:09
*/
public class ShowAllBooksServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//指定服务器编码,解码方式
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
out.write("本网站的书:<br/>");
Map<String, Book> books = DButil.findAllBooks();
for (Map.Entry<String,Book> book: books.entrySet()) {
//target='_blank':跳转到商品详情页面打开一个新窗口
out.write("<a href='"+req.getContextPath()+"/servlet/BookDetail?id="+book.getKey()+"' target='_blank'>"+book.getValue().getName()+"</a><br/>");
}
out.print("<hr/>最近浏览过的书:<br/>");
Cookie[] cookies = req.getCookies();
for (int i = 0; cookies != null && i < cookies.length; i++) {
if ("historyBookId".equals(cookies[i].getName())) {//判断是否有historyBookId的key的cookie
String value = cookies[i].getValue();//1-2-3
String[] ids = value.split("-");
for (int j = 0; j < ids.length; j++) {
Book book = DButil.findBookById(ids[j]);
out.print(book.getName()+"<br/>");
}
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
}
ShowBookDetail.java:
package com.xu.history;
import com.xu.entity.Book;
import com.xu.util.DButil;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.LinkedList;
/**
* @auther xu
* @date 2022/4/12 - 7:28
*/
public class ShowBookDetail extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//指定服务器编码,解码方式
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
//通过Id获取书的详细信息
String id = req.getParameter("id");
Book book = DButil.findBookById(id);
out.print(book);//因为write()方法只能够输出字符串
//将浏览过的书id返回给客户端
String historyBookId = organizedId(id,req);
Cookie ck = new Cookie("historyBookId", historyBookId);
ck.setMaxAge(Integer.MAX_VALUE);
resp.addCookie(ck);
}
/**
*客户端 showAllBooks showBookDetail
* 没有Cookie 1 historyBookId=1
* 有Cookie,但是没有historyBookId 1 historyBookId=1
* historyBookId=1 2 historyBookId=2-1
* historyBookId=1-2 2 historyBookId=2-1
* historyBookId=1-2-3 2 historyBookId=2-1
* historyBookId=1-2-3 4 historyBookId=4-1-2
*/
private String organizedId(String id, HttpServletRequest req) {
Cookie[] cookies = req.getCookies();
if (cookies == null) {
return id;
}
//查找有没有name叫做historyBookId的cookie
Cookie historyBook = null;
for (int i = 0; i < cookies.length;i++) {
if ("historyBookId".equals(cookies[i].getName())) {
historyBook = cookies[i];
}
}
//如果没有historyBookId的cookie,则还返回id
if (historyBook==null) {
return id;
}
//对应已经有historyBook
String value = historyBook.getValue();//2-1-3
String[] values = value.split("-");//将字符串以"-"进行切割
LinkedList<String> list = new LinkedList<>(Arrays.asList(values));//创建被切割的单个字符一个链表形式
if (list.size() < 3) {//1 2
if (list.contains(id)) {
list.remove(id);//再一次访问id=2的书,如果原先历史记录有id=2,就将2在链表中移除,再在链表头部插入id=2(2->1)
}
} else {
if (list.contains(id)) {//1 2 3
list.remove(id);//再一次访问id=2的书,如果原先历史记录有id=2,就将2在链表中移除,再在链表头部插入id=2(2->1->3)
} else {//1 2 3
list.removeLast();//3本书都不是同一个id,移除最后一个Id,再在链表头部插入id=4(4->1->2)
}
}
list.addFirst(id);//最新书的id添加到最前面
StringBuffer sb = new StringBuffer();
for (int i = 0; i < list.size(); i++) {
if (i>0) {
sb.append("-");
}
sb.append(list.get(i));
}
System.out.println(sb);//1-2-3
return sb.toString();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
}
测试结果:
2.session
1.HttpSession对象原理
1.作用域
HttpSession作用域比Request大,比getContext()作用域小:
如果访问的是Context作用域:
一个浏览器窗口访问该Context作用域的数据,开启另一个浏览器窗口也访问访问Context作用域对象(application),这两个浏览器窗口
数据是共享的
如果访问的是Session作用域:
一个浏览器窗口访问Session作用域的数据,开启另一个浏览器窗口访问Session作用域的数据,这两个浏览器窗口都是访问在服务器端
各自的Session数据,数据不是共享的.只要窗口不关,访问多个Servlet,都可以共享该窗口的Session数据
如果访问的是Request作用域:
一次请求之内的可以共享Request数据,下一次经过了服务器端响应数据的回传会导致下一次发送请求时数据更新
更改一下:直接输出到浏览器
2.浏览器如何实现一个Session为一个用户浏览器服务?
3.在同一个浏览器窗口之下,查看一下不同servlet页面所对应的Session所对应的Id是否相同
2.购物车功能的实现:
xml:
ShowAllBookServlet.java:
package com.xu.shoppingCar;
import com.xu.entity.Book;
import com.xu.util.DButil;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
/**
* @auther xu
* @date 2022/4/12 - 14:38
*/
public class ShowAllBookServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
out.print("该网站下有以下好书:<br/>");
Map<String, Book> allBooks = DButil.findAllBooks();
for (Map.Entry<String,Book> book:allBooks.entrySet()) {
out.print("<a href='"+req.getContextPath()+"/servlet/addCar?id="+book.getKey()+"'>"+book.getValue().getName()+"</a><br/>");
}
out.print("<a href='"+req.getContextPath()+"/servlet/showShopCar'>查看购物车</a>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
}
AddShoppCar.java:
package com.xu.shoppingCar;
import com.xu.entity.Book;
import com.xu.util.DButil;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
/**
* @auther xu
* @date 2022/4/12 - 14:52
*/
public class AddShoppCar extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
//根据id得到书
String id = req.getParameter("id");
Book book = DButil.findBookById(id);
//得到session对象
HttpSession session = req.getSession();
//从Session中取出list(购物车)
List<Book> list = (List<Book>)session.getAttribute("ShoppingCar");
if (list == null) {
list = new ArrayList<Book>();
}
list.add(book);
session.setAttribute("ShoppingCar",list);//把list添加到Session域中
out.print("购买成功,将跳转到主页面");
resp.setHeader("refresh","2;url="+req.getContextPath()+"/servlet/showAllBook");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
}
ShowShoppingCar.java:
package com.xu.shoppingCar;
import com.xu.entity.Book;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
/**
* @auther xu
* @date 2022/4/12 - 15:07
*/
public class ShowShoppingCar extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
//得到Session对象
HttpSession session = req.getSession();
List<Book> books = (List<Book>)session.getAttribute("ShoppingCar");
if (books==null) {
out.print("你还什么都没买");
//设置2秒钟后跳转
resp.setHeader("refresh","2;url="+req.getContextPath()+"/servlet/showAllBook");
return;
}
for (Book book:books) {
out.print(book.getName()+"<br/>");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
}
test结果:
什么都没买:
买了书:
买了如下3本书:
重复买,会导致重名:(待解决)
报错:
原因:
3.HttpSessionAPI:
补充:
1.Session依赖于cookie(因为Session的id存储在cookie中)
2.保存用户登录的信息一般往Session中放
3.Session存活时间的设定--session.setMaxInactiveInterval(20);//20s
4.Session对象的销毁
3.内部原理
找不到:
1.(浏览器默认Session存活时间为30分钟),浏览器并没有将cookie存入硬盘,浏览器没关(保证cookie存活),服务器也没关,但是人在半小时后再回来浏览网页,虽然请求头中仍然有关于Session的Id,但是此时HttpSession对象已经销毁了,通过该Id去寻找Session域,找不到,就从步骤2开始。
补充方法(不常用)
4.session状态
注意:序列化(钝化)之后,用户的数据将从内存中保存到硬盘,反序列化(激活)时又可以将数据加载进来,关闭服务器也无妨(有疑问)
5.客户端禁用Cookie后的会话数据保存问题
1.问题:
2.解决:重写url
解决原理:我们可以观察到,url后面的jsessionid的编号是一样的,代表是服务器端同一个Session对象,应该是将该Session对象编号在响应报文与请求报文中进行传递,通过直接访问该编号对应的Session域,达到访问在Session对象中存储的数据的目的(即使请求头中没有cookie类型 的数据)。