程序员社区

【Servlet-2】详解HttpSession

在这里插入图片描述

文章目录

      • 1.HttpSession接口简介
      • 2.Session域属性的设置
      • 3. Session工作原理

1.HttpSession接口简介

Session,即会话,是web开发中的一种会话状态跟踪技术。前面所述的Cookie也是一种会话跟踪技术。Cookie是将会话状态保存在客户端,而Session则是将会话状态保存在了服务器端。
何为会话?用户打开浏览器,从发出第一次请求开始,一直到最终关闭浏览器,就表示一次会话的完成。
在这里插入图片描述
在这里插入图片描述

2.Session域属性的设置

在这里插入图片描述
在这里插入图片描述
先看request的域属性:
在SessionDemo1中设置request域对象,然后再在OtherServlet类中取出域对象的值,看是否能取到。

import java.io.IOException;

@javax.servlet.annotation.WebServlet("/SessionDemo1")
public class SessionDemo1 extends javax.servlet.http.HttpServlet {
    protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
        //获取用户提交参数
        String username = request.getParameter("username");

        //将参数放在request域
        request.setAttribute("user",username);
        response.getWriter().print("SessionDemo1:"+username);
    }

    protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
        this.doPost(request, response);
    }
}
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 java.io.IOException;

@WebServlet("/OtherServlet")
public class OtherServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //从request域中读取user属性
        Object user = request.getAttribute("user");
        response.getWriter().print(user);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

在这里插入图片描述
可以看到,request对象代表一次请求,request域属性只能在同一次请求之间传递数据,所以两个不同的请求之间是无法传递数据。如果想要传递数据需要使用请求转发与重定向。

再来看Session域属性的设置:

先访问SessionDemo2可以看到Session=null
在这里插入图片描述
先访问SessionDemo1,再访问SessionDemo2,可以看到Session有值
并且在Request域中取不出request域中的值
Session域中恶意取出request域中的值
在这里插入图片描述
在这里插入图片描述
总结:
对于request对象作用于一次请求之间
对于session对象作用于一次会话之间
多次请求转发都共用一个Session对象。

对于request的getSession()的用法:
如果要向Session中写入数据,则需要使用getSession(true),即getSession()方法
存在Session对象就直接使用,没有Session对象就创建新的。
如果要向Session中读取数据,则需要使用getSession(false)方法
存在Session对象就直接使用,没有Session对象就返回null。因为只有已存在的session中国才有数据,新的session中没有数据。

3. Session工作原理

在服务器中系统会为每个会话维护一个Session。不同的对话对应不同的session。那么系统时如何识别各个session对象的?即如何做到同一会话过程中,一直使用的是同一个Sesison对象呢?

SessionDemo1文件:

package 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;
import java.io.PrintWriter;

@WebServlet("/SessionDemo1")
public class SessionDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取用户提交参数
        String username = request.getParameter("username");

        //将参数放在request域
        request.setAttribute("user",username);

        //获取Session对象
        HttpSession session = request.getSession();

        //向Session域中写入值
        session.setAttribute("username",username);
        PrintWriter out = response.getWriter();
        out.println("username="+username);
        out.println("session="+session);
    }

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

SessionDemo2文件:

package 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;
import java.io.PrintWriter;

@WebServlet("/SessionDemo2")
public class SessionDemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //从request域中读取user属性
        Object user = request.getAttribute("user");

        //获取Session,必须写成false,因为一旦为true,就会重新创建session,此时session里面并没存值
        HttpSession session = request.getSession(false);

        //从Session中读取指定属性
        Object username=null;
        if(session!=null){
            username = session.getAttribute("username");
        }

        PrintWriter out = response.getWriter();
        out.println("SessionDemo2:user="+user);
        out.println("SessionDemo2:username="+username);
        out.println("Session="+session);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

在火狐浏览器中:
可以看到两个Session对象相同
在SessionDemo2中可以获取SessionDemo1中设置的域属性的值
【Servlet-2】详解HttpSession插图9
【Servlet-2】详解HttpSession插图10
在谷歌浏览器中:
可以看到两个Session对象相同,但是火狐浏览器的session对象和谷歌浏览器的session对象不同。
在SessionDemo2中可以获取SessionDemo1中设置的域属性的值
在这里插入图片描述
在这里插入图片描述
既然谷歌浏览器和火狐浏览器的session对象不同,那么如何保证不错呢?

  1. 写入Session列表:
    服务器对当前应用中的Session是以Map的形式进行管理的,这个Map称为Session列表
    该Map的Key是一个32长度的随机串,这个随机串称为JSESSIONID,value为Session对象的引用。
    当用户第一次提交请求时,服务端Servlet中执行到request.getSession()方法后,会自动生成一个Map.Entry对象,key为根据某种算法生成的JSESISONID,value为新创建的Httpsession对象。
    在这里插入图片描述

  2. 服务器生成并发送Cookie
    在将Session信息写入Session列表后,系统会自动将JSESSIONID作为name,32长度的随机字符串作为value,以Cookie的形式放在响应头中,并随着响应,将该cookie发送到
    在这里插入图片描述客户端。

  3. 客户端接收并发送Cookie
    客户端收到Cookie后会将其存放到Cookie的缓存中。即,只要客户端浏览器不关闭,浏览器缓存中的Cookie就不会消失。
    当用户提交第二次请求时,会将缓存中的这个Cookie伴随着请求的头信息,一块发给服务端。
    在这里插入图片描述

  4. 从Session列表中查找
    服务端从请求中读取到客户端发送过来的Cookie,并根据Cookie的JSESSIONID的值,从Map中查找响应Key对应的value,即Session对象。然后对该Session对象的域属性进行读写操作。

赞(0) 打赏
未经允许不得转载:IDEA激活码 » 【Servlet-2】详解HttpSession

相关推荐

  • 暂无文章

一个分享Java & Python知识的社区