Tomcat自动生成会话JSESSIONID

一、request.getSession(true)和request.getSession(false)的区别

request.getSession(true):若存在会话则返回该会话,否则新建一个会话,默认为true;

request.getSession(false):若存在会话则返回该会话,否则返回NULL;

当向Session中存放登录信息时,一般建议:HttpSession session =request.getSession();

当从Session中获取登录信息时,一般建议:HttpSession session =request.getSession(false);

最近用到session来存储获取用户登录信息,使用过程中经常会出现获取不到session的情况。

所以对request.getSession()的几种情况查了相关资料,以作知识储备。

在Java Web项目中,用到request.getSession()一般是存储信息到session中或者从session中获取信息。

一般有三种参数设置方式:

  1. request.getSession()
    这是常用的方式,从当前request中获取session,如果获取不到session,则会自动创建一个session,并返回新创建的session;如果获取到,则返回获取到的session;

  2. request.getSession(true)
    这种方法和第一种一样,只是增加了一个true参数,告诉它在获取不到的时候自动创建session;

  3. request.getSession(false)
    这种方法与上两种的区别,就是在获取不到session的时候,不会自动创建session,而是会返回null。

在使用过程中,一般

想要存储到session中时,使用request.getSession();

想要获取session中的信息时,使用request.getsession(false),并在获取后对session变量进行是否为null的判断,再进行下一步操作。


二、JSESSIONID简介

JSESSIONID就是一个cookie,Servlet容器(tomcat,jetty)用来记录用户session。

2.1、什么时候浏览器自动生成JSESSIONID会话cookie?

  • 创建会话时,即调用request.getSession()的时候;

  • 访问html是不会创建session的,第一次访问JSP页面默认是会创建session的,可以在JSP页面里面关掉自动创建session。我们可以通过添加以下JSP指令:<%@ page session="false" %>就可以禁用JSESSIONID

2.2、览器禁止Cookie时进行URL重写?

服务端在内存里创建session,需要种Cookie,除了在request header里面设置Set-Cookie以外,tomcat等容器有一个URL重写机制。这个机制是浏览器Cookie不可用时的一个兜底策略,通过在URL后面加上;jsessionid=xxx来传递session id,这样即使Cookie不可用时,也可以保证session的可用性。

其中调用Request对象的isRequestedSessionIdFromCookie判断浏览器Cookie是否可用,里面逻辑也很简单,是读取request里面有没有传JSESSIONID这个Cookie。所以网上有些人说第一次访问,其实只要客户端没有传JSESSIONID,tomcat都假定Cookie不可用。

2.3、JSESSIONID什么时候生成并传递到前端的?

如果客户端请求的cookie中不包含JSESSIONID,服务端调用request.getSession()时就会生成并传递给客户端,此次响应头会包含设置cookie的信息

如果客户端请求的cookie中包含JSESSIONID,服务端调用request.getSession()时就会根据JSESSIONID进行查找对象,如果能查到就返回,否则就跟没传递JSESSIONID一样;

2.4、Servlet中调用request.getSession()时底层发生了什么事件?

访问方式:浏览器->服务器

1.如果servlet中没有调用request.getSession()方法,那么服务器永远都不会创建JSESSIONID。

2.如果servlet中调用request.getSession()方法那么情况分为以下两种情况:

 2.1  如果是第一次访问servlet,那么request.getSession()会创建一个JSESSIONID,并且在响应头里面有设置:

 Set-Cookie:JSESSIONID=********************************; Path=/虚拟项目名; HttpOnly

2.2  如果不是第一访问servlet,那么此次浏览器访问该项目的时候,请求头会带有:

Cookie:JSESSIONID=*********************************

request.getSession()会先去获取请求头的JSESSIONID,并且在服务器里面查找该ID,如果该session对象还存活(tomcat默认session的存活时间为30分钟,过了30分钟后,该session对象会被摧毁)则直接获取该session,如果该session已经被摧毁了,则重新又创建一个session对象,重复步骤2.1.

注意:jsp默认调用getSession()方法。


三、如何实现浏览器禁用Cookie后继续使用Session

方法1:

首先要明白:session是在服务器端创建并保存在服务器端,当代码中创建session时会相应地创建sessionID保存在服务器端,同时服务器向浏览器响应信息时会以cookie形式 (其实就是“JSESSION:sessionID”的键值对)返回并保存到浏览器本地中。一旦当前浏览器的进程要取服务器对应的保存在session的信息时候,就会取出刚才保存在cookie中对应的sessionID和服务器端的sessionID进行对比,相同就能取出你想要的信息,不能就不能取出。

好了,明白这一点后,我们就可以即使浏览器禁止了cookie也能用session。因为在一般情况下(即没禁时候),我们不需把sessionID保存到cookie中,因为一般情况下浏览器会自动的;然而当禁止时候,就需要我们主动的把sessionID写入到cookie中。那么问题就解决了。

主动把sessionID写到cookie中:这里其实也可以设置存储JSESSIONID的cookie存活时间

public void doGet(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException {
 
	response.setContentType("text/html;charset=utf-8");
	PrintWriter out = response.getWriter();
	//先用一次Session,就会自动创建Session的id
	HttpSession session=request.getSession();
	session.setAttribute("mess","你关闭了浏览器我还是给你看到session");
	//自己把SessionID保存在cookie中
	Cookie cookie=new Cookie("JSESSIONID", session.getId());
	//设置cookie保存时间
	cookie.setMaxAge(60*20);
	//被创建的cookie返回浏览器
	response.addCookie(cookie);
	out.println("添加Session成功!");
}

直接取就可以了:

String mess=(String)request.getSession().getAttribute("mess");  
out.println(mess);  

方法2:

URL重写

不用保存SessionID到cookie中,而是动态地把当前用户的SessionID添加到程序的各超链接或转发地址中,那么就可以确保用户的唯一。response.encodeRedirectURL(url)是一个进行URL重写的方法, 使用这个方法的作用是为了在原来的url后面追加上Jsessionid 。 目的是保证即使在客户端浏览器禁止了cookie的情况下,服务器端仍然能够对其进行事务跟踪。

//动态改写URL
String url = response.encodeRedirectURL("/UserManager/BuyBookCL");
PrintWriter.println("<a href='"+url+"'>加入购物车</a>");
//在返回时也要加入 URL地址重写
String url = response.encodeRedirectURL("/UserManager/home");
PrintWriter.println("<a href='"+url+"'>返回主页面</a><br/>");

例如这样:

功能:物品加入购物车后,点击返回主页面,主页面显示刚才加入到购物车的物品,当然了,这里是考虑浏览器禁止cookie情况下。


四、Token和JWT区别

Token都是服务器生成并传递给客户端的,普通token会存在服务端,json web token不用存而已。

JSON Web Token(JWT)是Token的一种实现方案,服务端通过私钥加密用户信息自包含于JWT长字符串的payload载荷中。JWT验证客户端请求发来的token信息,直接在服务端使用私钥解密校验就可以,而不用像普通token在服务端的内存和Redis缓存中保存token信息。

4.1、什么是token?

token的意思是“令牌”,是服务端生成的一串字符串,作为客户端进行请求的一个标识。

当用户第一次登录后,服务器生成一个token并将此token返回给客户端,以后客户端只需带上这个token前来请求数据即可,无需再次带上用户名和密码。

简单token的组成;uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,token的前几位以哈希算法压缩成的一定长度的十六进制字符串。为防止token泄露)。

4.2、token和JWT是什么关系?

为什么实际场景使用的 token 是一个短字符串,如下

25d9048a-dacb-45c3-ac0c-28be4340c8c1

而 JWT 是一个长字符串,如下

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0.rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM
  • Token是一个很宽泛的概念,翻译为令牌,一般用来表示经过验证之后得到的凭证,长度没有什么限制,多长都可以。JWT是 JSON Web Token,它也自称是一种token,jwt就是一个很具体的标准了,用点号分为三段,分别表示头、信息和签名。Token有很多种,可以是标准的,也可以是你自己定义的,jwt则是其中一种token,而且是标准的token。和我们自己随意定义的token差别大是很自然的,因为我们自己定义的token只需要用来识别用户登录状态,一般很短的唯一uuid都可以实现,通过它可以唯一查询缓存中的用户信息,所以比较短。

  • Token是无状态协议中认证用户的一种形式,相比于传统的cookie,不受域名限制;JWT只是一种实现形式,通过在客户端存储加密后的用户信息payload来降低服务端压力。

参考链接:

关于JSESSIONID

java服务器何时创建Session

jsp中session存在问题

猜你喜欢

转载自blog.csdn.net/CSDN2497242041/article/details/115203341
今日推荐