美文网首页程序员
Java Web开发中的会话管理

Java Web开发中的会话管理

作者: SpaceCat | 来源:发表于2019-01-21 01:19 被阅读38次

HTTP协议使用的是无状态连接。客户浏览器与服务器建立连接,发出请求,得到响应,然后关闭连接。换句话说,连接只为一个请求/响应而存在。
由于连接不会持久保留,所以容器认不出做第二个请求的客户与前一个请求的客户是同一个客户。对于容器而言,每一个请求都来自一个新的客户。
这时候,就需要用到会话(session)。

1、什么是会话?

下面是维基百科的解释:

In computer science, in particular networking, a session is a temporary and interactive information interchange between two or more communicating devices, or between a computer and user (see login session). A session is established at a certain point in time, and then ‘torn down’ - brought to an end - at some later point. An established communication session may involve more than one message in each direction. A session is typically stateful, meaning that at least one of the communicating parties needs to hold current state information and save information about the session history in order to be able to communicate, as opposed to stateless communication, where the communication consists of independent requests with responses.

在计算机网络中,会话是两个或者多个通讯设备之间或者人和电脑之间临时的信息交换。会话在某个时间点创建,在其后的某个时间点被销毁。一个已创建的会话一般在每个方向上都包括一条或者多条消息。和无状态的通讯中只包含相互独立的请求响应不同,会话是有状态的,也就是说,参与通讯的各方都要保留关于会话历史的状态信息,以便能够相互通信。

2、Java Web开发中会话的使用

在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),一个浏览器独占一个session对象(默认情况)。因此,在需要保存用户数据时,服务器程序可以把用户数据写到用户浏览器独占的session中,当用户使用浏览器访问其它程序时,其它程序可以从用户的session中取出该用户的数据,为用户服务。
Java Web开发中,容器以某种方式吧会话ID作为响应的一部分交给客户,而客户把会话ID作为请求的一部分发回。最简单常用的方式是通过cookie交换这个会话ID信息。

2.1 创建一个会话和从请求中得到一个会话

2.1.1 创建一个会话

在Java Web开发中,创建一个会话,只需要用:

HttpSession session = request.getSession();

通过这种方式,在服务方法中请求一个会话,容器会自动完成具体的工作,主要包括:

  • 创建一个新的HttpSession对象。
  • 生成唯一的会话ID。
  • 建立新的Cookie对象。
  • 将会话ID和Cookie关联。
  • 在响应中设置Cookie(设置Http响应的Set-Cookie首部)。

2.1.2 从请求中得到一个会话

浏览器在发送请求时,会自动将Cookie中的信息,放在http请求的首部,上送到服务器端。这样,服务器端就能够拿到之前写在Cookie中的会话ID,然后,利用该会话ID,可以得到会话对象。而这些操作,容器中也有封装的实现,编程中只需要调用即可。
实际上,从请求中得到会话,也是用上面的方法:

HttpSession session = request.getSession();

该方法会判断当前请求是否包含一个会话ID cookie:如果包含,找到与该ID匹配的会话;如果不包含会话ID cookie或者没有与该会话ID匹配的当前会话,就会创建一个新的会话对象。

2.2 如何判断会话是否是新创建的

从上面可以看到,创建一个会话和从请求获得一个会话的方式是一样的。那么,怎么判断会话是刚刚创建的,还是已经存在的呢?Session对象有一个isNew()方法,下面是一个例子。

package com.web.test;

import javax.servlet.ServletException;
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;

/**
 * Created by chengxia on 2018/12/3.
 */
public class ServletCookieTest extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.print("Test Session isNew().<br/>");
        HttpSession session = request.getSession();
        if(session.isNew()){
            out.println("This is a new session. Is this your first time here?");
        }else{
            out.println("Welcome Back!");
        }
        out.flush();
        out.close();
    }

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

这样,在浏览器中,第一次访问这个Servlet的时候,就会看到:


First Access

说明当前会话是新创建的。而第二次访问该servlet的时候,就会看到:


Second Access

同时,在上面第二个图中,可以看到,浏览器地址栏左方有一个圆圈i的图标,点击这个图标可以查看网站信息。从弹出的对话框中,可以看到已经确实会话ID信息已经写入了浏览器Cookie。如下图:


Cookie Set

有时候,如果只是想得到一个已有的会话,只在没有request.getSession()方法的时候,传入一个布尔型的参数,该参数用于标识在没有已存在会话的前提下是否要创建新会话对象,false表示不会创建新会话对象,这时候,该方法就会返回null。而传入true参数的情况,就和缺省的没有参数的情况一样。

2.3 浏览器禁用Cookie时的会话处理机制

如果浏览器禁用了cookie,那前面提到的通过Cookie来传递会话ID的方法就不好用了。这时候,就需要用到url重写。
简单的说,就是在请求的URL中通过参数将会话ID传递到服务器端。这样,服务端的程序就能够根据传过来的会话ID,获得会话对象。当然,这些操作,在容器的机制中,都有封装好的实现,只需要调用即可。下面是一个例子:

package com.web.test;

import javax.servlet.ServletException;
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;

/**
 * Created by chengxia on 2018/12/3.
 */
public class ServletUrlEncodeTest extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        HttpSession session = request.getSession();
        out.print("<html><body>");
        out.print("<a href=\"" + response.encodeURL("/ServletUrlEncode.Test") + "\">Test Link</a>");
        out.print("</body></html>");

        out.flush();
        out.close();
    }

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

当浏览器Cookie没有禁用,第一次访问该servlet时,容器会采取双保险的策略,既设置cookie,也在重写url时,添加会话ID作为参数。如下代码运行结果如下:


Cookie Allow, First Access in URL encode

可以看出,容器对URL进行了重写,在其中添加了sessionid参数。
但是,当点击页面上的超链接,再次访问该servlet时,容器可以从重写的url中拿到会话ID,而且发现浏览器上送了Cookie信息。这样,容器就认为该浏览器没有禁用cookie,后续的访问中,在对url进行重写时,就不会添加会话ID参数了。如下图:


Cookie Allow, Second Access in URL encode
如果这时候,如果删除并禁用Cookie,然后,通过页面上的链接(链接中没有会话ID作为参数)访问该servlet,这时候容器发现Cookie中没有上送会话ID信息,而且url参数中也没有。这时候,容器又会在重写url时加入会话ID信息。如下图:
Cookie Forbidden

此外,如果想把请求重定向到另外一个URL,但是,仍然想使用会话,可以用一个专门的url重写方法:

reponse.encodeRedirectURL("/ServletUrlEncode.Test")

3、总结

了解了Java Web开发中,基本的会话管理机制,对于后续使用会话有很大的帮助。对于会话,可以在其中设置属性,添加监听等。

参考资料

相关文章

  • Java Web开发中的会话管理

    HTTP协议使用的是无状态连接。客户浏览器与服务器建立连接,发出请求,得到响应,然后关闭连接。换句话说,连接只为一...

  • Java web开发——会话管理篇

    引言## 什么是会话简单来说,用户打开浏览器 -> 访问一些服务器内容 -> 关闭浏览器,这一操作,称之为一次会话...

  • 【译】StackOverflow:java中管理session的

    这篇文章来自于StackOverflow中的问答,主要讨论了web服务器会话管理的原理。原文 问题:Java中管理...

  • Spring Session 实现分布式会话管理

    1、分布式会话管理概述 在Web项目开发中,会话管理是一个很重要的部分,用于存储与用户相关的数据。通常是由符合se...

  • 浅谈Web会话

    会话是大家开发Web应用的常用技术,那么会话是什么,会话的用途还有工作原理又是什么? 在web应用中,作为客户端的...

  • Servlet 学习

    Java web项目结构目录 前言 Java web 是指用Java开发的web项目。Java web开发至今已有...

  • 会话与状态管理

    Web应用中的会话与会话状态 Web应用的会话状态是指Web服务器与浏览器在会话过程中产生的状态信息,借助会话状态...

  • Django的Cookie And Session介绍

    Cookie web开发中,使用session来完成会话跟踪,session底层依赖Cookie技术 Django...

  • Shiro的两种配置方式

    Apache Shiro是一款Java 安全框架,可以用于完成认证、授权、加密、会话管理、与Web集成、缓存等功能...

  • Javaweb开发学习路线及Java三大框架分享

    Java web开发是什么? Java web开发,是用Java技术来解决相关web互联网领域的技术总和。web包...

网友评论

    本文标题:Java Web开发中的会话管理

    本文链接:https://www.haomeiwen.com/subject/gvkqjqtx.html