背景知识:
- 我们都知道http是无状态的,因此我们无法通过http来标识用户,而有些信息或者资源只能给特定的用户看,例如用户的信息等等,这时候就出现了会话技术。
- 会话:一个会话包含多个http请求,它的作用主要用于这些http请求之间数据的共享。
上一篇文章中我们简单介绍了Cookie这个客户端会话技术。今天我们来聊聊另一个会话技术Session。
Session的原理:Session其实是依赖于Cookie的,当服务器开启Session后,浏览器访问服务器时,服务器会设置一个响应头Set-Cookie,其值是一个字符串(SessionID)用来标识当前Session的信息,默认键名则不同的语言各不同,例如在java中键名是JSESSIONID。当浏览器下次再访问服务器时会携带这个Cookie值,这时候服务器会根据SessionID找到与之对应的Session对象,这时我们刚刚在该对象上设置的信息就能获取到啦,以此来实现多个http请求之间数据的共享。具体如下:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取Session对象
HttpSession session = req.getSession();
// 设置Session信息
session.setAttribute("name", "weixin");
}
当然这个键名小伙伴是可以自定义的:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
// 自定义键名为Session,当然我们可以设置cookie的过期时间,path值,domain值
// 等等,具体可以查看《浅谈Cookie》
Cookie cookie = new Cookie("Session", session.getId());
resp.addCookie(cookie);
}
那么如何获取我们刚刚设置的Session信息呢?
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
// 获取刚刚设置的值
System.out.println(session.getAttribute("name"));
}
注意:Session对象其实在Java中就是一个域对象,什么是域对象呢?说白了就是用来共享数据用的。它们有一个共同的特点就是设置共享数据时使用setAttribute()方法,而获取共享数据时使用getAttribute()方法。
以上简单介绍了Session的原理和一些基本的操作,接下来谈谈它的一些注意事项:
1. 服务器端一直保持的开启状态,但是客户端关闭之后再请求,默认情况下两次得到的Session对象是同一个吗?不是。因为我们在上面提到Session是基于Cookie的,而在上一篇讲Cookie中提到,Cookie默认情况下是存储在内存中,浏览器关闭之后也随之删除了。因此第二次访问服务器时,由于没有SessionID携带,这个时候服务器又会重新创建一个Session对象并将与之对应的SessionID随着响应头Set-Cookie返回给浏览器。说到这里,机智的小伙伴们应该就能猜到,如果设置相应的Cookie持久化存储,那么两次访问得到的Session对象就是同一个了。
HttpSession session = request.getSession();
Cookie cookie = new Cookie("JSESSIONID", session.getId());
cookie.setMaxAge(60 * 60);
response.addCookie(cookie);
2. 客户端保持开启的状态,服务器端关闭之后再开启,这时候得到的Session对象是同一个吗?不是。不是同一个对象这很好理解,毕竟服务器关闭之后内存资源都被释放了,再开启内存资源就重新分配,那得到的对象肯定是不一样的。但是我们得保证原来的Session信息不被丢失。出于这个目的,引入了Session钝化和Session活化两个技术。什么是Session钝化呢?将Session对象序列化到硬盘中。什么是Session活化呢?将序列化在硬盘中的Session对象加载到内存中。
这里需要注意:Session的活化和钝化Tomcat已经帮我们完成了,在服务器关闭时Tomcat会在web应用程序下新建一个SESSIONS.ser文件,然后当服务器再次开启时会读取该文件的内容转成Session对象并删除该文件。其次,活化的Session对象和原来的Session其实并不是同一个对象,很明显它们的内存地址是不一样的,但是它们存储的信息是一样的。
3. 什么时候Session对象会被销毁?一种情况就是上面说的服务器关闭。还有一种情况就是调用invalidate()方法:
HttpSession session = req.getSession();
session.invalidate();
除了上述两种情况外,还有一种就是设置存活时间:
session.setMaxInactiveInterval(int seconds);
以上就是Session的一些注意事项,最后我们说说Session的特点:
- Session是服务端会话技术,相比于Cookie它更加安全,并且它支持存储任意类型的数据,不像Cookie只支持单一的字符串类型。
- 当然Session也存在一些弊端,由于Session是服务端的机制,因此当Session对象过多时会占用服务器的资源并带来内存压力,其次扩展性也不好,在当前服务器设置的Session只能在当前服务器获取,虽然可以通过其他技术手段解决但是总体来说扩展性还是不佳的。
以上就是关于Session的一些分享啦,感谢阅读。