java会话中有什么角色_Java Web开发中的会话管理

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().
");

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的时候,就会看到:

90072d4fb1cf?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

First Access

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

90072d4fb1cf?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

Second Access

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

90072d4fb1cf?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

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("

");

out.print("Test Link");

out.print("");

out.flush();

out.close();

}

protected void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

this.doPost(request, response);

}

}

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

90072d4fb1cf?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

Cookie Allow, First Access in URL encode

可以看出,容器对URL进行了重写,在其中添加了sessionid参数。

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

90072d4fb1cf?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

Cookie Allow, Second Access in URL encode

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

90072d4fb1cf?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

Cookie Forbidden

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

reponse.encodeRedirectURL("/ServletUrlEncode.Test")

3、总结

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

参考资料

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值