session是域对象,作用范围默认是一次会话
只要浏览器不关闭,客户端请求服务器中的任何一个资源session域对象均有效
一.预习(Session持久化):
这里有些知识点需要提前强调下,我们知道session是服务器端技术,用于在服务器端存储对象,其活跃周期为一次会话
一次会话指客户端浏览器是否被关闭掉
浏览器一旦关闭,服务器端session不会消失,但是客户端浏览器与服务器端的session联系便被取缔
浏览器在此访问服务器还会认识之前的那个session吗?
不会!
所以session有了以下的持久化规则:
- 每个session域对象创建时都携带有唯一的编号,称为sessionID
- session域对象创建后,需要将sessionID存储于cookie中并响应会客户端
- 浏览器在此请求服务器时会携带存储sessionID的cookie,并将此ID与服务器中sessionID对比
1.测试前准备:
- session设置程序:SetSession.java
- session校验程序:VerifySession.java
2.代码展示:
***SetSession.java
package controller.session;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
/**
* @Author weihuanwen
* @Date 2019/7/29 8:07
* @Version 1.0
*/
@WebServlet(urlPatterns = "/ss")
public class SetSession extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
String jessionId = session.getId();
System.out.println("JSESSIONID ::: "+jessionId);
Cookie cookie = new Cookie("JSESSIONID",jsessionId);
cookie.setMaxAge(10*60);
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
***VerifySession.java
package controller.session;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
/**
* @Author weihuanwen
* @Date 2019/7/29 8:07
* @Version 1.0
*/
@WebServlet(urlPatterns = "/vs")
public class VerifySession extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取session
HttpSession session = req.getSession();
//获取sessionId
String jessionId = session.getId();
System.out.println("JSESSIONID ::: "+jsessionId);
//执行session手动销毁
session.invalidate();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
3.测试
①访问请求路径:http://localhost:8080/sr/ss
前端cookie展示:

控制台输出展示:
JSESSIONID ::: AE35E1AA194D6BAD0D0E47F8BA8C7AD7
②访问请求路径: http://localhost:8080/sr/vs
前端cookie展示:

控制台输出展示:
JSESSIONID ::: AE35E1AA194D6BAD0D0E47F8BA8C7AD7
此过程中执行了一次session的手动清除
③访问请求路径:http://localhost:8080/sr/ss
前端cookie展示:

控制台输出展示:
JSESSIONID ::: 5FEB295741BD9C8439947DE7EFC1C464
④访问请求路径:http://localhost:8080/sr/vs
前端cookie展示:

控制台输出展示:
JSESSIONID ::: 5FEB295741BD9C8439947DE7EFC1C464
4.总结:
cookie中携带的JSESSIONID指定的session在服务器端下落不明时
①getSession()会生成新的Session对象
②同时会将新的Session的SessionID响应回前端作为JSESSIONID
二.session的获取
| 方法 | 描述 |
|---|---|
| HttpSession getSession() | 获取对应的HttpSession对象 |
| HttpSession getSession(boolean create) | 获取对应的HttpSession对象 |
1.HpSession getSession()的内部执行流程
- 获取名称为"JESSIONID"的cookie
- cookie==null,创建新的HttpSession对象sessionNew,分配唯一sessionId,并将"JsessionId=sessionID"存入cookie
- cookie!=null,依据获取SessionId在内存找寻HttpSession对象sessionExist
- sessionExist==null,创建新的HttpSession对象sessionNew,分配唯一sessionId,并将"JsessionId=sessionID"存入cookie
- sessionExist!=null,返回sessionExist
2.HttpSession getSession(boolean create)介绍
当create==true时,功能如同getSession()
当create==false时
- 获取名称为"JESSIONID"的cookie
- cookie==null,返回null
- cookie!=null,依据获取SessionId在内存找寻HttpSession对象sessionExist
- sessionExist==null,返回null
- sessionExist!=null,返回sessionExist
3.关于网上所谓session获取时的陷阱的个人理解
归结为下面的问题:
"当因为某种原因session被销毁(invalidate)或者自销毁(TimeOut)后,服务器端如何得知其已经被销毁?"
此时需要如下判断:
HttpSession session = req.getSession(false);
if (session != null){
String jessionId = session.getId();
System.out.println("JSESSIONID ::: "+jessionId);
}
当需要对session操作且发现session不存在时,是否需要创建新的session已经成为一种需求的问题了!
三.session的其他方法介绍
| 方法 | 描述 |
|---|---|
| setAttribute(String var1, Object var2) | 设置session值 |
| setMaxInactiveInterval(int var1) | 设置当前会话时间 (session的存货时间) (单位:秒,设置为负数|0时为永久不超时) |
| ServletContext getServletContext() | 获取Servlet上下文对象 |
| long getLastAccessedTime() | 最后一次成功获取session属性值的时间(EP:1564369071060) |
| String getId() | 获取session的唯一编号-->前端的JSESSIONID |
| long getCreationTime() | 获取session的创建时间(1970-1-1至创建时的毫秒值) |
| removeAttribute(String var1) | 移除session的属性 |
| void invalidate() | 将session设置失效(tomcat中session默认存活时间为30min) |
四."session遗失"的假象
现实中有些用户存在禁止cookie的行为,导致服务器端session"失效"
原因:
用户禁止了cookie后,服务器端接收到请求后获取不到cookie数据
自然解析不到JSESSIONID,所以也就找不到对应的session对象了
解决的方案如下:
- 客户端提示用户不要禁止cookie
- url重写
这里着重解释下url重写!
实现方法:
| 方法 | 描述 |
|---|---|
| HttpServletResponse.encodeURL(String url) | 用于对表单action和超链接的url地址进行重写 |
| HttpServletResponse.encodeRedirectURL(String url) | 用于对sendRedirect方法后的url地址进行重写 |
1.测试前准备:
- url重写程序:LoseSession.java
- 重定向目标程序:TargetSession.java
- 测试标准:重定向前后session的ID一致即可
2.代码展示:
***LoseSession.java
package controller.session;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
/**
* @Author weihuanwen
* @Date 2019/7/29 10:21
* @Version 1.0
*/
@WebServlet(urlPatterns = "/ls")
public class LoseSession extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//进行url重写
String sessionID = req.getSession().getId();
System.out.println("url重写前,LoseSession [sessionID ::: "+sessionID);
String path = resp.encodeRedirectURL(req.getContextPath()+"/target");
resp.sendRedirect(path);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
***TargetSession.java
package controller.session;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
/**
* @Author weihuanwen
* @Date 2019/7/29 11:58
* @Version 1.0
*/
@WebServlet(urlPatterns = "/target")
public class TargetSession extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/*
主要是确定这里是否会生成新的session对象
目标:
这里不会产生新的session对象,而是同url重写前一致
*/
HttpSession session = req.getSession();
String sessionID = session.getId();
System.out.println("url重写后,TargetSession [sessionID ::: "+sessionID);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
3.测试
①清除客户端浏览器cookie
②访问请求路径:http://localhost:8080/sr/ls
③请求后前端地址栏地址:http://localhost:8080/sr/target
④控制台输出如下:
url重写前,LoseSession [sessionID ::: CBA491CF87C7DD9CFEB51A0D004C563C
url重写后,TargetSession [sessionID ::: CBA491CF87C7DD9CFEB51A0D004C563C
⑤重复②控制台输出如下:
url重写前,LoseSession [sessionID ::: CBA491CF87C7DD9CFEB51A0D004C563C
url重写后,TargetSession [sessionID ::: CBA491CF87C7DD9CFEB51A0D004C563C
4.总结:
使用url重写避免了每次无cookie访问服务时都会生成新session的问题!
本文详细阐述了Session的工作原理,包括其在服务器端的存储机制、生命周期管理及与cookie的关系。探讨了Session的获取方法、常见问题及解决方案,如Session持久化、Session丢失的假象及其应对策略。
1953

被折叠的 条评论
为什么被折叠?



