`
benbenming
  • 浏览: 110298 次
  • 性别: Icon_minigender_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开发者提供一个可以方便地存储会话信息的地方。 

话状态跟踪API 

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

查看当前请求的会话对象 

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


查看和会话有关的信息 

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引擎将保持会话有效。负数表示会话永远不会超时。 

在会话对象中保存数据 

如上节所述,读取保存在会话中的信息使用的是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); 


实例:显示会话信息 

下面这个例子生成一个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);
}
}  
分享到:
评论

相关推荐

    十、会话状态

    10.1 会话状态概述 HTTP协议的“无状态”(Stateless)特点带来了一系列的问题。特别是通过在线商店购物时,服务器不能顺利地记住以前的事务就成了严重的问题。它使得“购物篮”之类的应用很难实现:当我们把商品...

    华为设备BFD实战,双向转发检测BFD详解.doc

    BFD控制报文是UDP报文,端口号3784,BFD提供异步检测模式,连续3个没有收到BFD控制报文,则认为BFD会话状态down。 三、BFD配置实施 AR2和SW5及SW6配置OSPF并建立邻居关系,详细了解OSPF相关知识可以参考HCIP OSPF...

    华为 NE20E-S V800R010C10SPC500 配置指南 - BFD配置

    通过创建BFD会话,可以实现快速检测网络中链路故障。...15 配置BFD会话修改端口状态表 16 配置BFD与接口联动功能 17 配置BFD会话进入AdminDown状态 18 配置静态自协商BFD for TE 19 配置BFD会话认证信息 20 维护BFD

    BFD和NQA技术原理.doc

    BFD 会话管理包括会话状态、会话迁移过程和会话建立方式。 会话状态: * Down:会话处于 Down 状态或刚刚创建。 * Init:已经能够与对端系统通信,本端希望使会话进入 Up 状态。 * Up:会话已经建立成功。 * ...

    Android Telephony 概述分析

    Android Telephony 概述分析 Android Telephony 是一个核心组件,负责处理移动设备的电话、短信和SIM卡功能。在Android系统中,它构建了一个复杂的架构,与硬件接口(RIL,Radio Interface Layer)紧密协作,确保...

    网络安全数据可视化概述.docx

    流级的流量监控会将一次网络会话的数据流聚合起来,只记录会话信息的方式数据量更小,也更加易于理解和管理.状态监控数据是指网络中各种软硬件资源的运行状态信息,如CPU 利用率、网络吞吐率、邮件服务是否正常等等...

    实验内容:使用会话技术.docx

    【实验内容概述】 本次实验主要涉及了Web应用开发中的会话技术,具体包括Cookie和Session的使用,以及在实际场景中的应用。实验旨在让学生理解如何通过这两种技术来维持用户状态,实现用户数据的持久化存储。 1. *...

    FTP服务器.pptx

    FTP服务器 一、FTP服务器概述 FTP客户端 端口21 数据传输终止 会话状态继续维 持 端口1068 端口21 连接建立 端口1068 端口21 维持会话状态 端口1068 FTP服务器端 FTP会话终止 连接断开 端口20 数据传输 端口1045 ...

    sip协议总体概述.pdf

    中期呼叫交易则可以在不改变SIP会话状态的情况下执行,比如在通话中添加或删除参与者。 3. **构建支持业务处理能力的基础结构**:SIP协议的扩展可以创建一个更加灵活的框架,支持各种业务处理,如重叠信令、DTMF...

    Java-Shiro学习思维导图.zip

    学习如何在 Shiro 中管理用户会话状态。 掌握会话的创建、维护和销毁。 密码加密: 学习如何使用 Shiro 进行密码的加密和验证。 了解不同的密码加密算法和安全性。 Remember Me 功能: 理解 Remember Me 功能的

    Novation诺维逊 Launchpad mini MK1&MK2 用户说明书.pdf

    Novation诺维逊 Launchpad mini MK1&MK2 用户说明书.pdf ...本文档提供了 Launchpad mini 的使用指南,涵盖了硬件设置、Ableton Live 设置、会话模式、导航会话视图、按钮颜色指示和会话概述等方面的知识点。

    Head First Servlets and JSP(中文版) 第三部分(共三部分)

    6 会话状态:会话管理 7 作为JSP:使用JSP 8 没有脚本的页面:无脚本的JSP 9 强大的定制标记:使用JSTL 10 JSTL也有力不能及的时候:定制标记开发 11 部署Web应用:Web应用部署 12 要保密,要安全:Web应用...

    Informatica PowerCenter V8功能概述

    是一个用于监控和管理PowerCenter服务器的图形界面,用户可以在这里配置服务器、管理用户权限、查看日志和监控作业运行状态。 4. **Repository Manager** Repository Manager是用于管理Repository的工具,用户...

    Head First Servlets and JSP(中文版) 第一部分(共三部分)

    6 会话状态:会话管理 7 作为JSP:使用JSP 8 没有脚本的页面:无脚本的JSP 9 强大的定制标记:使用JSTL 10 JSTL也有力不能及的时候:定制标记开发 11 部署Web应用:Web应用部署 12 要保密,要安全:Web应用...

    TWAIN Direct Specification- RESTful API

    例如,从"state"到"status"的改变,以及加入RFC(Request for Comments)标准,增加了错误处理和会话状态管理。 **内容概览** 规范中包含了术语表、参考资料、概述、目标、最佳实践、客户端、扫描仪、HTTPS安全、...

    Head First Servlets and JSP(中文版) 第二部分(共三部分)

    6 会话状态:会话管理 7 作为JSP:使用JSP 8 没有脚本的页面:无脚本的JSP 9 强大的定制标记:使用JSTL 10 JSTL也有力不能及的时候:定制标记开发 11 部署Web应用:Web应用部署 12 要保密,要安全:Web应用...

    数据库实例概述.pptx

    而PGA则是为每个用户进程单独分配的内存,存储用户特定的信息,如会话状态、SQL语句解析结果等。 SGA的主要组件包括: 1. 数据高速缓冲区:存储从数据文件中读取的数据,以提高数据访问速度。数据高速缓冲区由脏...

    EPC网络概述.pdf

    EPC 网络概述 EPC 网络是 LTE(Long-Term Evolution,长期演进)网络的一个重要组成部分,负责处理用户的移动性管理、承载管理、鉴权认证等功能。EPC 网络主要由多个网元组成,包括 HSS、MME、SGW、PGW、e-NodeB、...

    ORACLE错误一览表.docx

    4. ORA-00021, 22, 23: 这些错误与会话状态和权限有关,可能是因为会话已关联到其他进程,ID无效,或者尝试分离会话时出现问题。解决方法可能包括重新启动会话或调整会话设置。 5. ORA-00024, 25, 26: 这些错误涉及...

    HCIA-Security网络安全技术视频.zip

    2.2.3 状态检测技术和会话表 2.3 ASPF技术原理 3.0 NAT技术 3.1 NAT概述 3.2.1 源NAT 3.2.2 目的NAT 3.2.3 双向NAT 3.2.4 NAT Server 3.3 NAT ALG 4.1 双机热备概述 4.2.1 VRRP 4.2.2 VGMP 4.2.3 HRP 4.2.4 心跳线 ...

Global site tag (gtag.js) - Google Analytics