公众号查看文章
用现象说明问题,我在ServletSessonTest01中的代码设置了Session的属性
1public class ServletSessonTest01 extends HttpServlet {
2 @Override
3 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
4 //从request获得Session对象
5 HttpSession httpSession = req.getSession();
6 //设置Session的属性
7 httpSession.setAttribute("name","九月");
8 //设置Session最长超时时间为60秒,这里的单位是秒
9 httpSession.setMaxInactiveInterval(660);
10 }
11}
接着在ServletSessonTest02把Session的属性取出来,能取到在ServletSessonTest01中Session设置的属性.
1public class ServletSessonTest02 extends HttpServlet {
2 @Override
3 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
4 //从request获取HttpSession对象
5 HttpSession httpSession = req.getSession();
6 //获取从ServletSessonTest01设置的Session对象值
7 String value = (String) httpSession.getAttribute("name");
8 System.out.println("value: "+value);
9 //获取Sessio超时时间
10 int maxInactiveInterval = httpSession.getMaxInactiveInterval();
11 System.out.println("getMaxInactiveInterval: "+maxInactiveInterval);
12
13 }
14}
我在浏览器中新建一个会话,再次访问ServletSessonTest02,发现报了空指针异常的错误.
服务器是如何实现一个session为一个用户浏览器服务的?换个说法是为什么服务器能够为不同的用户浏览器提供不同session?
HTTP协议是无状态的,Session不能依据HTTP连接来判断是否为同一个用户。于是,服务器向用户浏览器发送了一个名为JESSIONID的Cookie,它的值是Session的id值。其实Session依据Cookie来识别是否是同一个用户。
简单来说:Session 之所以可以识别不同的用户,依靠的就是Cookie该Cookie是服务器自动颁发给浏览器的,不用我们手工创建的。该Cookie的maxAge值默认是-1,也就是说仅当前浏览器使用,不将该Cookie存在硬盘中
思路流程:当我们访问Servlet的时候,服务器就会创建一个Session对象,执行我们的程序代码,并自动颁发个Cookie给用户浏览器
当我们用同一个浏览器访问ServletSessonTest02的时候,浏览器会把Cookie的值通过http协议带过去给服务器,服务器就知道用哪一个Session。
而当我们使用新会话的浏览器(通过另外打开其他浏览器测试)访问ServletSessonTest02的时候,该新浏览器并没有Cookie,服务器无法辨认使用哪一个Session,所以就获取不到值
上面说了Session是依靠Cookie来识别用户浏览器的。如果我的用户浏览器禁用了Cookie了呢?绝大多数的手机浏览器都不支持Cookie,那我的Session怎么办?
我们来看看情况是怎么样的。用户浏览器访问ServletSessonTest01的时候,服务器向用户浏览器颁发了一个Cookie。
当用户浏览器访问ServletSessonTest02的时候,由于我们禁用了Cookie,所以用户浏览器并没有把Cookie带过去给服务器,我们实现不了记住密码或者给用户展示之前浏览过的商品等一些业务功能。
浏览器禁用了Cookie,Session好像不能用了。但是Java Web提供了解决方法,URL地址重写
HttpServletResponse类提供了两个URL地址重写的方法:
1encodeURL(String url)
2encodeRedirectURL(String url)
需要值得注意的是:这两个方法会自动判断该浏览器是否支持Cookie,如果支持Cookie,重写后的URL地址就不会带有jsessionid了【当然了,即使浏览器支持Cookie,第一次输出URL地址的时候还是会出现jsessionid(因为没有任何Cookie可带)】
对URL进行重写,看看能不能恢复没有禁掉Cookie之前的效果。
原则:把Session的属性带过去【传递给】另外一个Servlet,都要URL地址重写
1 @Override
2 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
3 //从request获得Session对象
4 HttpSession httpSession = req.getSession();
5 //设置Session的属性
6 httpSession.setAttribute("name","九月");
7 //设置Session最长超时时间为60秒,这里的单位是秒
8 httpSession.setMaxInactiveInterval(660);
9 String url = "/ServletSessonTest02";
10 resp.sendRedirect(resp.encodeURL(url));
11 }
URL地址重写的原理:将Session的id信息重写到URL地址中。服务器解析重写后URL,获取Session的id。这样一来,即使浏览器禁用掉了Cookie,但Session的id通过服务器端传递,还是可以使用Session来记录用户的状态。