Session详解(有案例验证)

 1.为什么我们需要使用Session保持会话机制

根本上来说就是因为http是一种无状态的协议,每一个请求和响应都是独立的,浏览器与服务器只会在请求与响应时建立联系,请求和响应结束后,之间的浏览器与服务器之间的联系自动断开了。这种机制能够在很大程度上减少服务器的压力,提高服务器的运行效率,但也因此带来了一些问题,例如:无法判断用户是否登录和难以获取更多用户的信息,为其提供个性化的服务;  

2.Session会话对象的生命周期

  • session对象是由WEB容器进行创建和管理的,保存在服务器端;

    获取创建Session对象

    HttpSession session = request.getSession(true|false);//参数默认是true,获取Session对象,如果获取不到Session对象,就重新创建一个Session对象。如果参数为false,则在获取不到Session对象后,不进行创建。

    Session超时设置:

    //Session默认是30分钟后过期,不设置就是默认;可以在xml文件中进行时间的配置

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

    手动销毁Session对象:

    Session.invalidate();

    • 创建阶段:创建于用户第一次访问应用程序时,服务器会为该用户自动创建一个session对象,而不是创建于第一次请求发送时,在该阶段中,服务器会为Session对象自动分配唯一的标识符,并将其作为第一次响应的部分返回给浏览器,之后作为cookie,存储在每次的请求中;【HttpSession.getsession()】

    • 活动阶段:在用户在应用程序中进行多个请求时,Session对象会一直保持活动状态。在该阶段中,用户可以通过Session对象存储和获取数据,以便在后续请求中使用。此外,每次与应用程序交互时,Session对象的计时器都会重置,以确保Session对象不会过期。[setAttribute getAttribute removeAttribute这三种方法来向session中存放数据、获取数据和移除数据]

    • 销毁阶段:销毁有两种方式:第一种是超时机制,Session过期后会自动销毁,第二种是使用session.invalidate()方法进行销毁。若用户直接关闭浏览器,不会销毁Session对象,但是在下一次登录时会获取到新的session对象,原有的Session会在超时之后自动销毁;

3.Session如何保存会话机制

会话机制的保存是通过session和Cookie的配合来实现的。

后端通过HttpSession session = request.getSession()来获取session对象,如果没有就创建一个Session,而如果写成HttpSession session = request.getSession(false)就是获取当前session对象,如果没有就不在创建了,从而能够保证session对象的唯一性。

我们通过以下代码来验证观点:(建议复制下来,在自己的电脑上运行,加深理解)

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet({"/test/session", "/check/session"})
public class servlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String servletPath = request.getServletPath();
        if (servletPath.equals("/test/session")) {
            HttpSession session = request.getSession();
            if (session != null) {
                System.out.println("sessionID="+session.getId());
                response.sendRedirect(request.getContextPath() + "/skip.html");
            }
        } else if (servletPath.equals("/check/session")) {
            HttpSession session = request.getSession(false);
            if (session != null) {
                System.out.println("有session");
                System.out.println("sessionID="+session.getId());
            }else{
                System.out.println("无session");
            }
        }
    }
}

代码运行之后,在地址栏中输入http://localhost:8080/testSession/test/session,会通过request.getSession()方法进行session对象的创建,sessionID也可以正常的输出。

在服务器session对象创建完成后,服务器会将创建的sessionID作为响应的一部分,返回给前端页面,我们可以在前端的响应表头中进行查看。而前端会将刚刚从响应中获取到的sessionID,保存到Cookie中,并在以后的请求中携带该Cookie,同后端创建的sessionId进行配对。

此时我们点击跳转的链接,我们发送的请求,会自动修改名为JSESSIONID的Cookie。后端会继续执行代码,通过request.getSession(false)方法,可以获取到我们之前创建好的session对象。可以看到,我们所获取的是同一个session对象。

我们现在换一种操作,回到skip.html页面,此时,我们手动删除前端的名为JSessionId的Cookie。

此时我们再次进行跳转会发现,后端通过request.getSession(false)不再能够获取到sessionId,后端输出,无session

这里我们得出结论:会话机制的保存是通过session和Cookie的不断验证来实现的,一旦前端请求没有携带名为JSESSIONID的Cookie或者前端携带的名为JSESSIONID的Cookie的值同后端Session中的值不匹配,都将导致会话机制的中断。如果单从会话机制的保存角度来看,我们在session域中存、取数据并不是必要的,session和Cookie本身就可以保持一种会话状态,在session域中存、取数据只是为了更加方便地进行数据的操作,提供一些个性化的服务。后端一旦创建session之后,前端便会在响应标头中获取sessionId,将其以Cookie的形式保存下来。以后的每一次请求都会自动携带该Cookie,Cookie同后端的sessionId进行配对,从而保持会话状态的进行。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值