JAVAWEB-NOTE08-会话

发布时间 2023-03-28 20:45:07作者: 男人的浪漫

会话概述

会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应
会话跟踪:维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据

服务器是不知道某几个请求是否是来自于同一个浏览器的,因为:HTTP协议是无状态的(为了保证每次请求都很快),每次浏览器向服务器请求时,服务器都会将该请求视为新的请求,因此我们需要会话跟踪技术来实现会话内数据共享

实现方式:
1.
客户端会话跟踪技术: Cookie
2.
服务端会话跟踪技术: Session

Cookie

基本使用

它是客户端的会话技术,将数据保存到客户端,以后每次请求都携带Cookie数据进行访问

演示实验:
我们首先创建一个demo servelet来给客户端发送cookie:

@WebServlet(value = "/CookieDemo1")
public class CookieDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建cookie对象
        Cookie cookie = new Cookie("username", "test-name");
        //发送cookie对象到客户端
        resp.addCookie(cookie);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

随后我们启动服务,在浏览器中访问这个资源

这时我们可以在当前网页发现cookie已经发送过来了

我们发送cookie的实验已经完成,接下来创建第二个资源来接受cookie,将第一个servlet的cookie显示在我们服务端的控制台上:

@WebServlet(value = "/CookieDemo2")
public class CookieDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //接受cookie
        Cookie[] cookies = req.getCookies();
        //按照name来将cookie取出
        for (Cookie cookie: cookies) {
            String userName = cookie.getName();
            if (userName.equals("username")){
                String value = cookie.getValue();
                System.out.println(userName+":"+value);
                break;
            }
        }

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

随后我们在浏览器中访问CookieDemo2这个资源

我们能够发现在控制台输出了我们刚刚在CookieDemo1中发送给客户端的Cookie,完成了两次请求之间的资源共享

原理

Cookie的实现是基于HTTP协议的
●响应头: set-cookie
●请求头: cookie

过程描述:
我们的servlet发送数据给浏览器的时候,发现我们要发送的数据是一个Cookie,那么它就将set-cookie我们这个对应的Cookie放到响应头中发送给客户端浏览器,浏览器存储在本地。当浏览器在本次会话想要访问第二个资源的时候,就会在请求头中带上自己当前的这个Cookie消息由cookie消息头发送给服务器。

还是之前的两个资源,我们访问一下,可以在第一个资源的响应头中看到set-cookie

在第二个资源的请求头中看到cookie

细节

存活时间

  • 默认情况下, Cookie 存储在浏览器内存中,当浏览器关闭,内存释放,则Cookie被销毁
  • setMaxAge(int seconds):设置Cookie存活时间
    1.正数:将Cookie写入浏览器所在电脑的硬盘,持久化存储。到时间自动删除
    2.负数: 默认值, Cookie在 当前浏览器内存中,当浏览器关闭,则Cookie被销毁
    3.零:删除对应Cookie

存储中文

  • Cookie不能直接存储中文
  • 如需要存储,则需要进行转码: URL编码

Session

基本使用

演示:
我们在demo1中设置session来存储数据:

@WebServlet(value = "/SessionDemo1")
public class SessionDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取session对象来存储
        HttpSession session = req.getSession();
        //利用session对象存储键值对
        session.setAttribute("username","test");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

然后我们用demo2来获取服务器中session对象的值

@WebServlet(value = "/SessionDemo2")
public class SessionDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取Session对象
        HttpSession session = req.getSession();
        //获取值
        Object username = session.getAttribute("username");
        System.out.println(username);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

代码写好之后,我们在我们的浏览器中,先访问SessionDemo1,再访问SessionDemo2,在服务端得到的结果如下:

原理

Session是基于cookie实现的(因为Session要基于Cookie来保证在一次会话的不同请求之间保证是同一个Session)
当某个请求访问到服务器时,如果我这时候创建的了session,那么Tomcat发现了我使用了session对象,那么会在返回给客户端的响应消息中加上一个set-cookie = id,这个id就是我们这个session的唯一标识码。然后当我们在当前会话再次请求其他资源的时候,本地浏览器发送的请求头就会带着cookie = id去访问服务器的资源

细节