`

会话

阅读更多
10 会话

   10.1 会话状态概述

  HTTP协议的“无状态”(Stateless)特点带来了一系列的问题。特别是通过在线商店购物时,服务器不能顺利地记住以前的事务就成了严重的问题。它使得“购物篮”之类的应用很难实现:当我们把商品加入购物篮时,服务器如何才能知道篮子里原先有些什么?即使服务器保存了上下文信息,我们仍旧会在电子商务应用中遇到问题。例如,当用户从选择商品的页面(由普通的服务器提供)转到输入信用卡号和送达地址的页面(由支持SSL的安全服务器提供),服务器如何才能记住用户买了些什么?

  这个问题一般有三种解决方法:

  Cookie。利用HTTP Cookie来存储有关购物会话的信息,后继的各个连接可以查看当前会话,然后从服务器的某些地方提取有关该会话的完整信息。这是一种优秀的,也是应用最广泛的方法。然而,即使Servlet提供了一个高级的、使用方便的Cookie接口,仍旧有一些繁琐的细节问题需要处理:

  从其他Cookie中分别出保存会话标识的Cookie。

  为Cookie设置合适的作废时间(例如,中断时间超过24小时的会话一般应重置)。

  把会话标识和服务器端相应的信息关联起来。(实际保存的信息可能要远远超过保存到Cookie的信息,而且象信用卡号等敏感信息永远不应该用Cookie来保存。)

  改写URL。你可以把一些标识会话的数据附加到每个URL的后面,服务器能够把该会话标识和它所保存的会话数据关联起来。这也是一个很好的方法,而且还有当浏览器不支持Cookie或用户已经禁用Cookie的情况下也有效这一优点。然而,大部分使用Cookie时所面临的问题同样存在,即服务器端的程序要进行许多简单但单调冗长的处理。另外,还必须十分小心地保证每个URL后面都附加了必要的信息(包括非直接的,如通过Location给出的重定向URL)。如果用户结束会话之后又通过书签返回,则会话信息会丢失。

  隐藏表单域。HTML表单中可以包含下面这样的输入域:<INPUT TYPE="HIDDEN" NAME="session" VALUE="...">。这意味着,当表单被提交时,隐藏域的名字和数据也被包含到GET或POST数据里,我们可以利用这一机制来维持会话信息。然而,这种方法有一个很大的缺点,它要求所有页面都是动态生成的,因为整个问题的核心就是每个会话都要有一个唯一标识符。

  Servlet为我们提供了一种与众不同的方案:HttpSession API。HttpSession API是一个基于Cookie或者URL改写机制的高级会话状态跟踪接口:如果浏览器支持Cookie,则使用Cookie;如果浏览器不支持Cookie或者Cookie功能被关闭,则自动使用URL改写方法。Servlet开发者无需关心细节问题,也无需直接处理Cookie或附加到URL后面的信息,API自动为Servlet开发者提供一个可以方便地存储会话信息的地方。

  10.2 会话状态跟踪API

  在Servlet中使用会话信息是相当简单的,主要的操作包括:查看和当前请求关联的会话对象,必要的时候创建新的会话对象,查看与某个会话相关的信息,在会话对象中保存信息,以及会话完成或中止时释放会话对象。

  10.2.1 查看当前请求的会话对象

  查看当前请求的会话对象通过调用HttpServletRequest的getSession方法实现。如果getSession方法返回null,你可以创建一个新的会话对象。但更经常地,我们通过指定参数使得不存在现成的会话时自动创建一个会话对象,即指定getSession的参数为true。因此,访问当前请求会话对象的第一个步骤通常如下所示:

HttpSession session = request.getSession(true);

  10.2.2 查看和会话有关的信息

  HttpSession对象生存在服务器上,通过Cookie或者URL这类后台机制自动关联到请求的发送者。会话对象提供一个内建的数据结构,在这个结构中可以保存任意数量的键-值对。在2.1或者更早版本的Servlet API中,查看以前保存的数据使用的是getValue("key")方法。getValue返回Object,因此你必须把它转换成更加具体的数据类型。如果参数中指定的键不存在,getValue返回null。

  API 2.2版推荐用getAttribute来代替getValue,这不仅是因为getAttribute和setAttribute的名字更加匹配(和getValue匹配的是putValue,而不是setValue),同时也因为setAttribute允许使用一个附属的HttpSessionBindingListener 来监视数值,而putValue则不能。

  但是,由于目前还只有很少的商业Servlet引擎支持2.2,下面的例子中我们仍旧使用getValue。这是一个很典型的例子,假定ShoppingCart是一个保存已购买商品信息的类:
HttpSession session = request.getSession(true); 
ShoppingCart previousItems =(ShoppingCart)session.getValue("previousItems"); 
if (previousItems != null) { 
 doSomethingWith(previousItems); 
} else { 
 previousItems = new ShoppingCart(...); 
 doSomethingElseWith(previousItems); 
} 

大多数时候我们都是根据特定的名字寻找与它关联的值,但也可以调用getValueNames得到所有属性的名字。getValuesNames返回的是一个String数组。API 2.2版推荐使用getAttributeNames,这不仅是因为其名字更好,而且因为它返回的是一个Enumeration,和其他方法(比如HttpServletRequest的getHeaders和getParameterNames)更加一致。

  虽然开发者最为关心的往往是保存到会话对象的数据,但还有其他一些信息有时也很有用。

  getID:该方法返回会话的唯一标识。有时该标识被作为键-值对中的键使用,比如会话中只保存一个值时,或保存上一次会话信息时。

  isNew:如果客户(浏览器)还没有绑定到会话则返回true,通常意味着该会话刚刚创建,而不是引用自客户端的请求。对于早就存在的会话,返回值为false。

  getCreationTime:该方法返回建立会话的以毫秒计的时间,从1970.01.01(GMT)算起。要得到用于打印输出的时间值,可以把该值传递给Date构造函数,或者GregorianCalendar的setTimeInMillis方法。

  getLastAccessedTime:该方法返回客户最后一次发送请求的以毫秒计的时间,从1970.01.01(GMT)算起。

  getMaxInactiveInterval:返回以秒计的最大时间间隔,如果客户请求之间的间隔不超过该值,Servlet引擎将保持会话有效。负数表示会话永远不会超时。

  10.2.3 在会话对象中保存数据

  如上节所述,读取保存在会话中的信息使用的是getValue方法(或,对于2.2版的Servlet规范,使用getAttribute)。保存数据使用putValue(或setAttribute)方法,并指定键和相应的值。注意putValue将替换任何已有的值。有时候这正是我们所需要的(如下例中的referringPage),但有时我们却需要提取原来的值并扩充它(如下例previousItems)。示例代码如下:
HttpSession session = request.getSession(true); 
session.putValue("referringPage", request.getHeader("Referer")); 
ShoppingCart previousItems = (ShoppingCart)session.getValue("previousItems"); 
if (previousItems == null) { 
  previousItems = new ShoppingCart(...); 
} 
String itemID = request.getParameter("itemID"); 
previousItems.addEntry(Catalog.getEntry(itemID)); 

session.putValue("previousItems", previousItems); 

 10.3 实例:显示会话信息

  下面这个例子生成一个Web页面,并在该页面中显示有关当前会话的信息。
package hall; 

import java.io.*; 
import javax.servlet.*; 
import javax.servlet.http.*; 
import java.net.*; 
import java.util.*; 

public class ShowSession extends HttpServlet { 
 public void doGet(HttpServletRequest request,HttpServletResponse response) 
 throws ServletException, IOException { 
  HttpSession session = request.getSession(true); 
  response.setContentType("text/html"); 
  PrintWriter out = response.getWriter(); 
  String title = "Searching the Web"; 
  String heading; 
  Integer accessCount = new Integer(0);; 
  if (session.isNew()) { 
   heading = "Welcome, Newcomer"; 
  } else { 
   heading = "Welcome Back"; 
   Integer oldAccessCount = 
   // 在Servlet API 2.2中使用getAttribute而不是getValue 
   (Integer)session.getValue("accessCount"); 
  if (oldAccessCount != null) { 
   accessCount = 
   new Integer(oldAccessCount.intValue() + 1); 
  } 
 } 
 // 在Servlet API 2.2中使用putAttribute 
 session.putValue("accessCount", accessCount); 

 out.println(ServletUtilities.headWithTitle(title) +"<BODY BGCOLOR=\"#FDF5E6\">\n" + 
     "<H1 ALIGN=\"CENTER\">" + heading + "</H1>\n" + 
     "<H2>Information on Your Session:</H2>\n" + 
     "<TABLE BORDER=1 ALIGN=CENTER>\n" + 
     "<TR BGCOLOR=\"#FFAD00\">\n" + 
     " <TH>Info Type<TH>Value\n" + 
     "<TR>\n" + 
     " <TD>ID\n" + 
     " <TD>" + session.getId() + "\n" + 
     "<TR>\n" + 
     " <TD>Creation Time\n" + 
     " <TD>" + new Date(session.getCreationTime()) + "\n" + 
     "<TR>\n" + 
     " <TD>Time of Last Access\n" + 
     " <TD>" + new Date(session.getLastAccessedTime()) + "\n" + 
     "<TR>\n" + 
     " <TD>Number of Previous Accesses\n" + 
     " <TD>" + accessCount + "\n" + 
     "</TABLE>\n" + 
     "</BODY></HTML>"); 
 } 
 public void doPost(HttpServletRequest request, 
  HttpServletResponse response) 
  throws ServletException, IOException { 
   doGet(request, response); 
 } 
} 
分享到:
评论

相关推荐

    asp.net 会话状态

    ASP.NET 会话状态是Web开发中用于保持用户在浏览多页应用时的状态信息的关键机制。由于HTTP协议的无状态特性,服务器无法自动记住不同请求之间的用户信息。为了解决这个问题,ASP.NET提供了会话状态功能,使得开发者...

    PHP企业微信会话存档扩展

    在企业微信的日常使用中,为了保障企业内部沟通的合规性、审计需求以及信息安全,企业微信提供了会话存档功能。这个功能允许企业保存并管理员工间的聊天记录,以便后续查阅或审计。而PHP作为广泛应用于Web开发的编程...

    java的springboot框架实现获取企业微信会话内容存档

    java的springboot框架获取企业微信会话内容进行存档,支持windows部署、linux下的docker部署; 能学到什么:企业微信获取会话的流程;企业微信的获取会话内容的公钥私钥加解密;获取企业微信会话内容; 阅读建议:此...

    springboot实现获取企业微信会话内容存档支持windows、linux部署配置

    java的springboot框架获取企业微信会话内容进行存档,支持windows部署、linux下的docker部署; 能学到什么:企业微信获取会话的流程;企业微信的获取会话内容的公钥私钥加解密;获取企业微信会话内容; 阅读建议:此...

    定时清除XP会话连接

    标题中的“定时清除XP会话连接”指的是针对Windows XP操作系统的一种优化策略,主要是解决系统由于过多的远程桌面或网络共享连接导致的问题。Windows XP默认情况下,最多只能支持10个并发的远程桌面会话,这对于需要...

    解决win7使用超级终端无法读取会话文件问题

    在Windows 7系统下,如果从XP系统中拷贝了超级终端程序并尝试运行,可能会遇到无法读取会话文件的问题。这个问题主要源于文件格式不兼容或缺少必要的依赖。 首先,我们需要理解超级终端的工作原理。超级终端是一款...

    crt批量添加会话

    "CRT批量添加会话" CRT(SecureCRT)是一款功能强大的终端仿真器,可以连接到多种类型的设备和服务器,但是在管理大量设备时,添加会话表的工作变得非常痛苦。为了解决这个问题,本文将介绍如何使用CRT快速添加会话...

    用户登录,会话跟踪

    在JavaWeb开发中,用户登录和会话跟踪是至关重要的环节。这涉及到用户身份验证、安全性以及用户体验等多个方面。本文将深入探讨如何使用session和cookie技术来实现会话跟踪。 首先,我们需要理解“会话”(Session...

    定时清除XP会话连接2代

    本程式的主要功能是:定时清除XP会话连接。 公司使用局域网上一台XP sp2/sp3系统的电脑连接打印机供打印,因为有在10多台电脑在用打印机,打印时常显示:连接数已达到最大值。 网上查得方法是:及时清除XP会话连接...

    Jboss下开发ejb应用之一会话bean的应用

    本文将围绕“Jboss下开发ejb应用之一会话bean的应用”这一主题,深入探讨如何在Jboss应用服务器上开发和部署会话Bean,以及涉及到的相关工具和源码。 会话Bean是EJB的一种类型,它代表了业务逻辑组件,为客户端提供...

    日语会话日语会话日语会话

    很抱歉,根据您提供的信息,标题和描述的内容都是重复的“日语会话”,而标签也是同样的“日语会话”。然而,对于一个专业的IT大师来说,这样的信息并不足以生成有关IT知识的具体内容,因为它们涉及到的是语言学习,...

    nginx+tomcat7+memcached session会话保持

    在构建高性能、高可用性的Web应用系统时,会话保持是一个关键环节,它涉及到用户登录状态、购物车信息等重要数据的持久化处理。本文将详细介绍如何在Nginx、Tomcat7和Memcached的环境下实现会话保持,确保用户在多台...

    F5负载均衡会话保持技术及原理技术白皮书.docx

    简单会话保持里另外一个很重要的参数就是连接超时值,BIGIP 会为每一个进行会话保持的会话设定一个时间值,当一个会话上一次完成到这个会话下次再来之前的间隔如果小于这个超时值,BIGIP 将会将新的连接进行会话保持...

    企业微信会话内容存档php扩展.zip

    企业微信会话内容存档是企业微信为企业提供的一项重要功能,它允许企业合规地存档内部及与客户的聊天记录,以便于后期审计、管理和数据分析。本压缩包“企业微信会话内容存档php扩展.zip”提供了针对PHP环境的扩展,...

    从pcap文件中析取所有TCP会话与UDP会话

    用于从pcap文件中析取所有TCP会话与UDP会话,主要讲述算法的组成。

    实验5 会话及其会话技术.docx

    Servlet 会话技术详解 在 Web 应用程序中,会话是一种非常重要的概念,用于记录和跟踪用户的交互行为。Servlet 提供了两种类型的会话技术,即 Cookie 和 Session,下面我们将详细介绍这两种技术的实现原理和应用...

    基于多策略的短文本信息流会话抽取

    互联网中存在大量的短文本信息流,需要对其进行会话抽取,将相同主题的内容合并到同一会话中。会话中的内容、时间和用户关系都会对会话抽取的性能产生影响,针对该问题提出了一种基于多策略的会话抽取算法。首先,...

    日语常用会话1000句 自己粘贴

    日语常用会话1000句.日语常用会话1000句.日语常用会话1000句.日语常用会话1000句.日语常用会话1000句.日语常用会话1000句.日语常用会话1000句.日语常用会话1000句.日语常用会话1000句.日语常用会话1000句.日语常用...

    qq临时会话器

    QQ临时会话器是一款针对腾讯QQ即时通讯软件的辅助工具,它主要的功能是为用户提供一个临时的交流平台,尤其适用于那些未添加对方为好友但仍需进行沟通的情况。在这个临时会话中,用户可以发送文字、表情、文件等,...

    日语会话.rar 日语会话.rar 日语会话.rar

    很抱歉,根据您提供的信息,这个压缩包"日语会话.rar"似乎包含了日语学习相关的资源,特别是可能是一个日语会话教程或参考材料。然而,具体的详细内容无法通过文件名"dsafdsaf.chm"来推断,因为这个文件名看起来是...

Global site tag (gtag.js) - Google Analytics