Session理解

本文深入解析Cookie和Session在会话跟踪中的作用与区别,探讨它们的实现方式及应用场景,包括如何利用URL重写实现Session跟踪。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Cookie和Session都可以实现会话跟踪,将上一次的请求传入下一次内,但它们的实现方式有一个显著的区别,如下:

  • Cookie:将当前会话的信息存在浏览器端,每次请求时将Cookie信息传入服务器
  • Session:将会话的信息存在服务器端,浏览器保存一个JSESSIONID,每次传入JSESSIONID去取信息

很显然,2种会话跟踪的实现方式,Session是在服务器端保持状态的方案,Cookie实在浏览器端保持状态的方案。对于Cookie而言,如果传输的状态信息较多,将较大的降低网络传输的效率和增大服务器的处理难度,因此Session显然在这种情况下是比较好的。

Session是基于Cookie来实现的,每次为一个客户端创建一个Session对象时,其实也是创建了一个Cookie对象,这个Cookie对象保存的就是JSESSIONID。服务器为每一个客户端创建的Session对象保存在服务器的内存中,Session对象有一个超时间隔时间,当离最后一次访问的时间超过的这个间隔时间之后,这个Session对象将会失效,变成一个垃圾对象,等待回收。默认超时间隔时间为30分钟,可以在<tomcat安装目录>\conf\Web.xml文件里面配置,如下:

<session-config>
<session-timeout>30</session-timeout>
</session-config>

注意conf\Web.xml文件配置和web应用程序的web.xml文件配置的作用域。

当浏览器不支持Cookie或关闭Cookie时,便不能用Cookie的方式来实现Session,这种情况应该很少。此时可以利用URL重写实现Cookie跟踪。按照正常访问网站的规则,用户是直接输入地址进入一个主页面,然后通过超链接进入其他页面,而直接输入地方访问其他页面时视为非法访问,不创建Session对象。当用超链接访问时,浏览器将会话标识号作为参数附加在超链接的URL地址后面就叫URL重写。HttpServletResponse接口中定义了两个完全用于URL重写的方法:

  • encodeURL:用于对超链接和form表单的action属性中设置的URL进行重写
  • encodeRedirectURL:用于对要传递给HttpServletResponse.sendRedirect方法的URL进行重写

对encodingURL的测试如下:

@WebServlet("/Session1")
public class SessionServlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out=resp.getWriter();
        HttpSession session=req.getSession();
        Integer sessionCount=(Integer)session.getAttribute("count");
        int count=0;
        if(sessionCount!=null){
            count=sessionCount.intValue();
        }
        out.println("当前会话中发生了"+(++count)+"次访问<br>");
        session.setAttribute("count",new Integer(count));
        count=0;
        ServletContext application=getServletContext();
        Integer applicationCount=(Integer) application.getAttribute("count");
        if(applicationCount!=null){
            count=applicationCount.intValue();
        }
        out.println("Web应用程序中发生了"+(++count)+"次访问<br>");
        application.setAttribute("count",new Integer(count));
        out.println("<a href='"+resp.encodeURL("Session2")+"'>访问Session2");
    }
}
@WebServlet("/Session2")
public class SessionServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out=resp.getWriter();
        HttpSession session=req.getSession();
        Integer sessionCount=(Integer)session.getAttribute("count");
        int count=0;
        if(sessionCount!=null){
            count=sessionCount.intValue();
        }
        out.println("当前会话发生了"+(++count)+"次访问<br>");
        session.setAttribute("count",new Integer(count));
        count=0;
        ServletContext application=getServletContext();
        Integer applicationCount=(Integer)application.getAttribute("count");
        if(applicationCount!=null){
            count=applicationCount.intValue();
        }
        out.println("Web应用程序发生了"+(++count)+"次访问<br>");
        application.setAttribute("count",new Integer(count));
        out.println("<a href='"+resp.encodeURL("Session1")+"'>访问Session1</a>");
    }
}

当访问Session1时,查看网页源码如下:

点击超链接,地址栏如下:

对于不支持Cookie而言的浏览器,实现Session跟踪就是以这种形式实现的,如果浏览器支持Cookie也采用了这种实现方式的话,第一次访问会将会话标识号附加到URL路径后,但后续响应消息则不在附加,这是因为创建Session时总是将会话标识号以Cookie的形式发送给浏览器,如果浏览器不支持或关闭Cookie,则不会回传这个标识号,如果支持,会回传,则服务器知道浏览器支持Cookie,便不在附加标识号到URL后。第一次访问时服务器不知道浏览器支不支持,所以也会附加标识号到URL后。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值