【JSP/Servlet-HTTP会话解析】

个人学习整理,如有不足之处,请不吝指教。转载请注明:@CSU-Max

Max之前的一篇关于Session 和 Cookie 的文章:cookie和session那些事

会话简介

web服务器跟踪客户状态的几种方式:

1、在html表单中加入隐藏字段,它包含用于跟踪用户状态的数据;

2、重写URL,及在URL中附带用户的状态信息;

3、使用cookie来传递用于跟踪客户状态的数据;

4、使用会话来跟踪用户状态的数据。

会话能够把用户与同一用户发出的不同请求之间关联起来。不同用户的会话应当是相互独立的。在web开发领域,会话机制是用于跟踪用户状态的普遍解决方案。会话是指在一段时间内,单个用户与web应用的一系列交互过程。在一个会话过程中,用户可以多次请求该web应用的同一页面,也可以访问该web应用中的其他页面。

在Servlet中有关于会话的 javax.servlet.http.HttpSession 接口,Servlet容器必须实现这一接口。当一个会话开始时,Servlet容器会创建一个HttpSession对象,将客户信息状态存储在该对象中,如购物车信息。Servlet容器为每个HttpSession对象分配一个唯一的标志符,称为SessionID。

会话的运作流程

1、当一个浏览器进程第一次请求访问某个web应用中任意一个支持会话的网页(也可以设置页面不支持会话,下文有介绍),Servlet容器会试图寻找HTTP请求中表示SessionID的Cookie,由于还不存在这样的Cookie,故此时就会开启一个新的会话,Servlet容器会创建一个HttpSession对象,并为其分配一个唯一的SessionID,在返回HTTP响应结果时,Cookie会附带该SessionID。当浏览器接收到HTTP响应结果之后,会把Cookie(带有SessionID)保存在客户端。

2、该浏览器进程继续访问该web应用中的任意支持会话的页面,在本次的HTTP请求中会包含带有SessionID的Cookie,Servlet容器会获取本次HTTP请求中的SessionID,该SessionID就是1中产生的,因此Servlet容器认为本次请求与上次请求处于同一个会话中,Servlet容器不会创建新的HttpSession对象,而是根据Cookie中的SessionID,找到内存中该SessionID对应的HttpSession对象。

3、重复步骤2,在当前会话销毁之前(关于会话的销毁下文有介绍),仍是在同一个会话中进行访问,故不会产生新的HttpSession对象。

通过代码实例来了解会话机制

在默认情况下,JSP页面都会支持会话,也可以通过代码显式控制支持会话:

<%@ page session = "true" %>

若web组件支持会话,当客户请求访问该web组件时,Servlet容器会自动查找HTTP请求中表示SessionID的Cookie,并向HTTP响应结果中添加表示SessionID的Cookie。在此过程中,若有与SessionID对应的HttpSession对象,则Servlet容器使用该对象,若没有,则Servlet容器会创建一个新的HttpSession对象。

web组件可以访问代表当前会话的HttpSession对象。

我们可以通过下面的实例代码来了解,新建一个web工程,在根目录下新建一个test.jsp,具体代码如下:

<%@ page language ="java" contentType="text/html; charset=utf-8"
      pageEncoding= "utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv= "Content-Type" content ="text/html; charset=utf-8">
<title> Insert title here</ title>
</head>
<body>
     <%
          Cookie[] cookies = request.getCookies();
           if (cookies == null) {
              out.println( "no cookie");
               return;
          }
           for ( int i = 0; i < cookies.length; i++) {
     %>
     <b >Cookie Name </b>
     <%=cookies[i].getName() %>
     <br >
     <b >Cookie Value </b>
     <%=cookies[i].getValue() %>
     <br >
     <b >Cookie Maxage</ b>
     <%=cookies[i].getMaxAge() %>
     <%
          }
     %>
</body>
</html>

1、打开一个浏览器进程,第一次请求访问test.jsp页面,会返回“no cookie”。

2、利用1打开的浏览器进程,再次访问test.jsp页面(即再按一次回车即可)。由于在1中,Servlet容器会向客户端发送一个包含SessionID的Cookie(上面已经讲到),所以本次的HTTP请求中会包含该Cookie,故test.jsp页面上会显示该Cookie的数据,如下图:

注:此处Cookie的maxage(有效期)属性值为 -1,表示该Cookie仅存在与当前的浏览器进程中,当浏览器关闭,该Cookie也就失效了,本次会话也结束了。

3、利用1打开的浏览器进程再多次访问test.jsp页面,页面显示的数据仍如上图所示。

4、重新打来一个浏览器进程,重复步骤1、2、3,会发现页面显示的Cookie Value不一样,即SessionID不一样,因为不同的浏览器进程对应不同的会话,每个会话都拥有一个唯一的SesionID。

5、在test.jsp中加入如下代码,使test.jsp不支持会话,再重新打开一个浏览器进程,多次访问test.jsp页面,结果都是显示“no cookie”。因为test.jsp显式要求不支持会话,所以Servlet容器不会创建HttpSession对象,也不会向客户端发送表示SessionID的Cookie。

HttpSession 的会话范围

会话的范围指的是浏览器端与一个web应用进行一次会话的过程。在具体实现时,会话范围与HttpSession对象的生命周期相对应,所以web组件只要共享同一个HttpSession对象,就能实现共享会话范围内的共享数据。

在HttpSession接口中关于在会话范围内存取共享数据有如下方法:

 /**
      * 向会话范围内存放共享数据
      */
     public void setAttribute(String name, Object value) {

     }

     /**
      * 返回会话范围内与name对应的共享数据
      */
     public Object getAttribute(String name) {
           return null;
     }

     /**
      * 返回会话范围内所有共享数据的name
      */
     public Enumeration getAttributeNames() {
           return null;
     }

     /**
      * 删除会话范围内与name对应的共享数据
      */
     public void removeAttribute(String name) {

     }

利用以上的方法,我们就可以在会话范围内存取共享数据了:

  HttpSession session = request.getSession();
           //将username 存储到会话范围内的共享数据中
          session.setAttribute( "username", username);

           //从会话范围内读取username
          currentUser = (String) session.getAttribute("username" );

在HttpSession接口中还有一些其他的访问会话的方法,想了解的可以自行研究。

HttpSession 的生命周期

在以下情况下,会开启一个新的会话,即Servlet容器会创建一个新的HttpSession对象:

1、一个浏览器进程第一次访问某个web应用中支持会话的任意一个网页。

2、当浏览器与web应用的上一次会话被销毁后,浏览器进程再次访问web应用中支持会话的任意一个网页。

注:当浏览器进程与web应用的一次会话被销毁之后,web服务器端相应的HttpSession对象结束其生命周期。当浏览器进程再次访问该web应用时,在它的HTTP请求中的Cookie中包含了之前已被销毁的SessionID,但是此时Servlet容器无法找到次SessionID对应的HttpSession对象,故Servlet容器会创建新的HttpSession对象,开启新的会话。

在以下情况下,会销毁一个会话,即Servlet容器会使HttpSession对象结束生命周期,并且存储在会话范围内的共享数据也会被销毁:

1、浏览器进程终止。

2、服务器端执行了HttpSession对象的invalidate()方法。

3、会话过期。

会话过期是指在会话开启之后,若在一段规定的时间内,用户没用和web应用进行交互,则Servlet容器会自动的销毁这个会话。HttpSession中的 setMaxInactiveInterval(int interval) 方法用于设置允许会话保持不活动状态的时间(以秒为单位),如果超过这个规定的时间,会话就会被Servlet容器销毁。若把
interval 参数设为负数,则表示会话永远不会过期。在Tomcat中,默认的会话保持不活动状态的时间是1800秒。

当一个会话开启后,如果浏览器进程突然关闭,Servlet容器无法立即知道浏览器进程已经关闭,因此Servlet容器中的HttpSession对象不会立即结束生命周期,会话会在浏览器进程关闭之后,进入不活动状态,等到超出上述规定的时间后,会话就会因为过期而被Servlet容器销毁。

为什么要有会话过期的机制呢?

我们知道,过多无用的HttpSession对象会影响web服务器的性能,销毁长期不活动的会话,可以及时释放这些HttpSession对象占用的内存空间。同时,会话过期机制也提高了web应用的安全性,防止未授权的用户访问会话。如某个用户访问某个web应用,之后并没有关闭浏览器进程,此时另一个用户使用该浏览器进程访问同一web应用,此时看到的是前一个用户的信息,这就给安全带来了隐患。

********************************************************************************

**          转载请注明出处:  @CSU-Max   http://blog.csdn.net/csu_max  
       **     ********************************************************************************

时间: 2024-08-10 21:30:15

【JSP/Servlet-HTTP会话解析】的相关文章

深入理解JSP/Servlet Session会话管理机制

HTTP 是一种无状态协议,这意味着每次客户端检索网页时,都要单独打开一个服务器连接,因此服务器不会记录下先前客户端请求的任何信息.它与FTP.Telnet等协议不同,FTP等协议可以记住用户的连接信息. 会话(Session)是指一个终端用户与交互系统进行通信的时间间隔,通常指从登陆系统到注销系统之间所经过的时间以及如果需要的话,可能还有一定操作空间.JSP有四种方式实现会话跟踪功能. Cookie 服务器在响应请求时可以将一些数据以"键-值"对的形式通过响应信息保存在客户端.当浏览

JSP/Servlet基础语法

相关学习资料 http://my.oschina.net/chape/blog/170247 http://docs.oracle.com/cd/E13222_01/wls/docs81/webapp/web_xml.html http://blog.csdn.net/liaoxiaohua1981/article/details/6761053 http://computer.c.blog.163.com/blog/static/102524482012314537670/ http://ww

JSP Servlet之间交换数据

摘自:<轻量级Java EE企业应用实战>第三版 对于每次客户端请求而言,web服务器大致需要完成以下步骤: 1.启动单独线程 2.使用I/O流读取用户的请求参数 3.从请求数据中解析参数 4.处理用户请求 5.生成响应数据 6.使用I/O流向客户端发送请求数据 1.2.6是通用的,由web服务器完成,3.4.5存在差异,因为不同请求里包含的请求参数不一样,处理用户请求的方式也不同,所生成的响应也不同,这3步由Servlet的_jspService()方法完成.当编写JSP页面时,页面的静态内

第二章.JSP/Servlet及相关技术详解

JSP的4种基本语法: 1.JSP注释: <%-- JSP注释部分 --%> 2.JSP声明: <%! //声明一个整型变量 public int count; //声明一个方法 public String info(){ return "hello"; } %> 3.输出JSP表达式: <%=count++%> 这句话代替了Java中的out.print(count++);但是注意输出表达式后面不能有分号. 4.JSP脚本: 1 <%@ pa

【Hibernate学习笔记】第二章节:JSP/Servlet及相关技术详解

JSP(Java Servr Page)和Servlet是Java EE规范的两个基本成员,他们是Java Web开发的重点知识,也是Java EE开发的基础知识.JSP和Servlet的本质是一样的,因此JSP最终必须编译成Servlet才能运行,或者说JSP只是生成Servlet的"草稿"文件.JSP的特点是在HTML页面中嵌入了Java代码片段,从而可以动态的提供页面内容. 1.Web应用和web.xml文件 JSP.Servlet.Listener和Filter等都必须运行在W

JSP/Servlet程序设计(入门书籍)

Web开发技术 1. 静态开发技术: (1)HTML      HTML是网站开发最基本的语言,是WEB的核心.所有后续的WEB开发技术都以HTML为基础. (2)CSS      CSS(Cascading Style Sheet)级联样式表. (3)JavaScript      JavaScript是一种基于对象和事件驱动的脚本语言.JavaScript程序可以直接嵌入HTML页面,作为一种客户端程序,允许用户与其进行交互. 2. 动态网页技术: 主要有ASP.ASP.NET.PHP和JS

jsp servlet基础复习 Part1

jsp和servlet的一些基础知识整理,用于备忘. 一.jsp与servlet的基本关系 1.jsp-->web容器-->servlet-->加载进容器的虚拟机执行-->输出执行结果给浏览器端 在这个过程,所有位于<%%>之外的值,都被认为是out.println()中的内容进行直接输出.详细理解看代码 <html> <% //例子说明:servlet和jsp的关系 boolean b = false; if(b){ %> 这里是内容一 <

Servlet 工作原理解析

-----转自许令波老师Servlet 工作原理解析  感觉写的很不错,保存下来,留着以后温习 从 Servlet 容器说起 要介绍 Servlet 必须要先把 Servlet 容器说清楚,Servlet 与 Servlet 容器的关系有点像枪和子弹的关系,枪是为子弹而生,而子弹又让枪有了杀伤力.虽然它们是彼此依存的,但是又相互独立发展,这一切都是为了适应工业化生产的结果.从技术角度来说是为了解耦,通过标准化接口来相互协作.既然接口是连接 Servlet 与 Servlet 容器的关键,那我们就

jsp servlet的区别和联系(转)

servlet是服务器端的程序,动态生成html页面发到客户端,但是这样 程序里有许多out.println(),java和html语言混在一起很乱.所以 后来推出了jsp.其实jsp就是servlet,每一个jsp在第一次运行时被 转换成servlet文件,再编译成.class来运行. 有了jsp,因此在MVC模式中servlet不再负责生成html页面,转而担任 控制程序逻辑的作用,控制jsp和javabean之间的流转. Servlet与Jsp的区别     * Servlet中没有内置对