上一篇地址:赶紧收藏!2024 年最常见 100道 Java 基础面试题(三十三)-CSDN博客
六十七、说一下session
的工作原理?
HTTP协议是无状态的,这意味着服务器在处理HTTP请求时无法识别请求之间的关联。为了在无状态的HTTP协议上实现有状态的会话,引入了session
(会话)的概念。以下是session
的工作原理:
1. 创建Session
当用户第一次发送请求到服务器时(通常是用户登录请求),服务器会创建一个session
对象。这个对象是服务器端的一个数据结构,用于存储用户的状态信息。
2. Session ID
为了将用户的请求关联到特定的session
,服务器会为每个session
生成一个唯一的标识符,称为session ID
。这个ID是创建session
时随机生成的。
3. 传递Session ID
服务器需要将session ID
传递给客户端,以便客户端在后续请求中发送回服务器。这通常通过以下几种方式实现:
-
Cookie:服务器可以在响应中设置一个名为
JSESSIONID
的cookie,该cookie的值即为session ID
。客户端浏览器会自动存储这个cookie,并在之后的每个请求中携带它。 -
URL重写:服务器也可以在生成的URL中嵌入
session ID
,这种方式不依赖于cookie,但可能会导致session ID
在日志和浏览器地址栏中可见。
4. 维持Session
客户端在每次请求时都会发送session ID
给服务器。服务器根据这个ID查找对应的session
对象,从而获取用户的状态信息。
5. Session超时
session
有一个超时时间,这个时间是从最后一次活跃开始计算的。如果超过这个时间,服务器可以认为用户已经不再活跃,从而销毁这个session
。
6. 显式注销Session
用户可以在完成操作后显式地注销session
。这通常通过请求服务器端的一个注销功能实现,服务器在收到注销请求后会销毁对应的session
对象。
示例代码:
创建Session:
// 在用户登录成功后创建session
HttpSession session = request.getSession(true); // true表示如果不存在则创建
session.setAttribute("username", "Kimi"); // 在session中存储用户信息
读取Session:
// 从session中读取用户信息
String username = (String) session.getAttribute("username");
传递Session ID:
// 使用Cookie传递session ID
response.addCookie(new Cookie("JSESSIONID", session.getId()));
// 或者使用URL重写传递session ID
String url = "http://example.com/page.jsp?JSESSIONID=" + session.getId();
注销Session:
// 注销session
session.invalidate();
总结:
session
通过session ID
来维持用户的状态,即使HTTP协议本身是无状态的。session ID
可以通过cookie或URL重写的方式传递。- 服务器端的
session
对象存储用户的状态信息,而客户端通过session ID
与服务器的session
关联。 - 合理使用
session
可以提高Web应用程序的交互性和用户体验,但也要注意安全性和性能。
六十八、如果客户端禁止cookie
能实现session
还能用吗?
如果客户端浏览器禁止了cookie,那么服务器通过cookie来维持会话(session)的方式就会受到影响,因为cookie是HTTP协议中用来存储会话信息的一种常用机制。不过,即使客户端禁止了cookie,服务器仍然有其他方法来实现会话跟踪,主要有以下几种替代方案:
-
URL重写: 服务器可以在生成的URL后面附加
session ID
,这种方式不依赖于cookie。例如,可以在每个链接后面附加一个参数,如http://example.com/page.jsp?JSESSIONID=123456
。这种方式的缺点是session ID
会在URL中可见,并且可能会在服务器日志中留下记录。 -
表单隐藏字段: 在HTML表单中使用隐藏字段来传递
session ID
。这种方式要求用户必须通过表单提交数据,对于所有通过表单提交的请求,服务器都可以从中获取session ID
。 -
<form action="submitPage.jsp" method="post"> <input type="hidden" name="JSESSIONID" value="123456" /> <!-- 其他表单字段 --> </form>
-
自定义HTTP头: 服务器可以要求客户端在HTTP请求中通过自定义的HTTP头来传递
session ID
。这种方法需要客户端浏览器的支持,并且可能需要一些额外的配置。 -
利用HTML5的Web Storage: HTML5引入了Web Storage API,包括localStorage和sessionStorage。这些提供了在客户端存储数据的能力,但它们并不是专门为会话跟踪设计的,且localStorage的安全性也需要考虑。
-
使用服务器端的隐藏变量: 在服务器端的JSP或Servlet中,可以使用隐藏变量来存储
session ID
,然后在服务器端进行跟踪。 -
利用SSL/TLS会话标识: 如果使用了SSL/TLS加密的HTTPS连接,可以利用SSL会话来标识和跟踪用户。这种方式依赖于SSL的会话机制,但并不常用。
注意事项:
-
安全性:不通过cookie传递
session ID
可能会带来安全隐患,因为session ID
可能会被截获或泄露。 -
便利性:URL重写和表单隐藏字段需要在每个请求中显式传递
session ID
,这可能会增加开发和维护的复杂性。 -
跨域问题:如果Web应用程序需要处理跨域请求,那么使用URL重写或表单隐藏字段可能会遇到问题。
总结:
- 即使客户端禁止了cookie,服务器仍然可以通过URL重写、表单隐藏字段等其他机制来维持会话状态。
- 每种替代方案都有其优缺点,需要根据具体的应用场景和安全需求来选择最合适的方法。
- 在不使用cookie的情况下,应特别注意保护
session ID
的安全,避免会话劫持等安全风险。