JavaWeb之Session会话管理

1 什么是Session

Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务。

2 Session的工作原理

浏览器A来访问BuyServlet,服务器会先给浏览器A创建Session(a)对象,里面保存着用户购买的商品洗衣机,当浏览器A访问PayServlet,服务器发现浏览器A有对应的Session(a)对象,于是从里面取出用户购买的商品洗衣机来结账。同样,当浏览器B来访问服务器的BuyServlet时,服务器也会为浏览器B创建Session(b)对象,里面存放着用户想购买的商品电视,当浏览器B访问PayServlet时,服务器会从Session(b)中取出用户想购买的商品电视进行结账操作。Session(a)和Session(b)是两个Session对象,分别保存浏览器A和浏览器B与服务器的会话信息,这样服务器在执行PayServlet时就知道用户想买什么商品了。


Session的工作原理

3 Session的生命周期

1、Session对象的创建:程序第一次调用到request.getSession()方法时说明客户端明确的需要用到session,此时创建出对应客户端的Session对象
2、Session对象的销毁:
(1)当Session对象30min没有被使用,则该Session对象超时被销毁
(2)程序中明确的调用session.invalidate()方法可以立即杀死该session对象
(3)当服务器被非正常关闭时,随着虚拟机的死亡而销毁
注意:如果服务器是正常关闭,还未超时的session会被以文件的形式保存在服务器的work目录下,这个过程叫做session的钝化。下次再正常启动服务器时,钝化着的session会被恢复到内存中,这个过程叫做session的活化。

4 用Session实现简单的购物结账界面

index.html



  
    index.html
    
  
  
  
    洗衣机
    结账
  

点击index.html的洗衣机访问服务器的BuyServlet,将商品洗衣机存放在服务器的Session对象中:

public class BuyServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String prop = request.getParameter("prop");
        prop = new String(prop.getBytes("iso8859-1"), "UTF-8");
        request.getSession().setAttribute("prop", prop);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

点击index.html的结账访问PayServlet,将Session对象中的商品洗衣机取出,并返回给浏览器:

public class PayServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        HttpSession session = request.getSession();
        String prop = (String) session.getAttribute("prop");
        response.getWriter().write("您购买的商品是:" + prop);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

5 Session的内部实现

服务器如何确定浏览器对应到哪个Session对象呢?这个又是如何实现的?下面我们就来讨论这个问题。
其实Session技术是基于Cookie实现的,具体过程如下:
1、浏览器A访问服务器的BuyServlet,服务器发现浏览器没有带Jsessionid的cookie请求头,认为浏览器A是第一次访问,创建一个新的Session对象,并且这个对象里面有个id值,这个id值会保存在name为Jsessionid的cookie响应头中通知浏览器A保存这个cookie
2、当浏览器A访问PayServlet时会带上Jsessionid这个cookie,服务器收到cookie后解析回去Jsessionid对应的值,然后查找到对应的Session对象,此时服务器就明确了到底是哪个浏览器来访问我了


Session的内部实现

Cookie中的Jsessionid

需要注意的是:默认情况下JSESSIONID 的path为当前web应用的名称,并且没有设置过MaxAge,是一个会话级别的cookie。这意味着一旦关闭浏览器再新开浏览器时,由于JSESSIONID丢失,会找不到之前的Session。我们可以手动的发送JSESSIONID cookie,名字和path设置的和自动发送时一样,但是设置一下MaxAge,使浏览器除了在内存中保存JSESSIONID信息以外还在临时文件夹中以文件的形式保存,这样即使重开浏览器仍然可以使用之前的session。

6 URL重写

如果浏览器禁用了Cookie,浏览器就没有办法JSESSIONID cookie,这样就用不了Session了。我们可以使用URL重写的机制,在所有的超链接后都以参数的形式拼接JSESSIONID信息,从而在点击超链接时可以使用URL参数的方式待会JSESSIONID,从而使用Session。将URL进行重写拼接上JSESSIONID的过程就叫做URL重写

    request.getSession() --在URL重写之前一定要先创建出Session,才有Session id,才能进行重写。
    response.encodeURL()--- 一般的地址都用这个方法重写
    response.encodeRedirectURL() --- 如果地址是用来进行重定向的则使用这个方法
<%@ page language="java" import="java.util.*" pageEncoding="utf-8" session="false"%>


  
  
  
  <%
    request.getSession();
  
    String url1 = request.getContextPath()+"/servlet/BuyServlet?prod=电视机";
    url1 = response.encodeURL(url1);
    String url2 = request.getContextPath()+"/servlet/BuyServlet?prod=冰箱";
    url2 = response.encodeURL(url2);
    String url3 = request.getContextPath()+"/servlet/PayServlet";
    url3 = response.encodeURL(url3);
   %>
    电视机
    冰箱
    结账
  

URL重写后的链接

需要注意的是:当用户关闭浏览器后再次打开,因为Session id变了,所以访问不到上次选定的商品,这个问题没法解决,因此URL重写用的不多。

你可能感兴趣的:(JavaWeb之Session会话管理)