|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
先谈谈我对java的一些认识。我选择java,是因为他语法简单,功能强大,从web,到桌面,到嵌入式,无所不能。但当我进一步了解了java后,感叹,java原来也有许多缺点。js|servlet10.1会话形态概述
HTTP协定的“无形态”(Stateless)特性带来了一系列的成绩。出格是经由过程在线商铺购物时,服务器不克不及顺遂地记着之前的事件就成了严峻的成绩。它使得“购物篮”之类的使用很难完成:当我们把商品到场购物篮时,服务器怎样才干晓得篮子里本来有些甚么?即便服务器保留了高低文信息,我们仍然会在电子商务使用中碰到成绩。比方,当用户从选择商品的页面(由一般的服务器供应)转到输出信誉卡号和投递地点的页面(由撑持SSL的平安服务器供应),服务器怎样才干记着用户买了些甚么?
这个成绩一样平常有三种办理办法:
Cookie。使用HTTPCookie来存储有关购物会话的信息,后继的各个毗连能够检察以后会话,然后从服务器的某些中央提取有关该会话的完全信息。这是一种优异的,也是使用最普遍的办法。但是,即便Servlet供应了一个初级的、利用便利的Cookie接口,仍然有一些烦琐的细节成绩必要处置:
从其他Cookie平分别出保留会话标识的Cookie。
为Cookie设置符合的取消工夫(比方,中止工夫凌驾24小时的会话一样平常应重置)。
把会话标识和服务器端响应的信息联系关系起来。(实践保留的信息大概要远远凌驾保留到Cookie的信息,并且象信誉卡号等敏感信息永久不该该用Cookie来保留。)
改写URL。你能够把一些标识会话的数据附加到每一个URL的前面,服务器可以把该会话标识和它所保留的会话数据联系关系起来。这也是一个很好的办法,并且另有当扫瞄器不撑持Cookie或用户已禁用Cookie的情形下也无效这一长处。但是,年夜部分利用Cookie时所面对的成绩一样存在,即服务器真个程序要举行很多复杂但单调冗杂的处置。别的,还必需非常当心地包管每一个URL前面都附加了需要的信息(包含非间接的,如经由过程Location给出的重定向URL)。假如用户停止会话以后又经由过程书签前往,则会话信息会丧失。
埋没表单域。HTML表单中能够包括上面如许的输出域:<INPUTTYPE="HIDDEN"NAME="session"VALUE="...">。这意味着,当表单被提交时,埋没域的名字和数据也被包括到GET或POST数据里,我们能够使用这一机制来保持会话信息。但是,这类办法有一个很年夜的弱点,它请求一切页面都是静态天生的,由于全部成绩的中心就是每一个会话都要有一个独一标识符。
Servlet为我们供应了一种不同凡响的计划:HttpSessionAPI。HttpSessionAPI是一个基于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。因而,会见以后哀求会话对象的第一个步骤一般以下所示:
HttpSessionsession=request.getSession(true);
10.2.2检察和会话有关的信息
HttpSession对象保存在服务器上,经由过程Cookie大概URL这类背景机制主动联系关系到哀求的发送者。会话对象供应一个内建的数据布局,在这个布局中能够保留恣意数目的键-值对。在2.1大概更早版本的ServletAPI中,检察之前保留的数据利用的是getValue("key")办法。getValue前往Object,因而你必需把它转换成加倍详细的数据范例。假如参数中指定的键不存在,getValue前往null。
API2.2版保举用getAttribute来取代getValue,这不但是由于getAttribute和setAttribute的名字加倍婚配(和getValue婚配的是putValue,而不是setValue),同时也由于setAttribute同意利用一个从属的HttpSessionBindingListener来监督数值,而putValue则不克不及。
可是,因为今朝还只要很少的贸易Servlet引擎撑持2.2,上面的例子中我们仍然利用getValue。这是一个很典范的例子,假定ShoppingCart是一个保留已购置商品信息的类:
HttpSessionsession=request.getSession(true);
ShoppingCartpreviousItems=
(ShoppingCart)session.getValue("previousItems");
if(previousItems!=null){
doSomethingWith(previousItems);
}else{
previousItems=newShoppingCart(...);
doSomethingElseWith(previousItems);
}
年夜多半时分我们都是依据特定的名字寻觅与它联系关系的值,但也能够挪用getValueNames失掉一切属性的名字。getValuesNames前往的是一个String数组。API2.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)。示例代码以下:
HttpSessionsession=request.getSession(true);
session.putValue("referringPage",request.getHeader("Referer"));
ShoppingCartpreviousItems=
(ShoppingCart)session.getValue("previousItems");
if(previousItems==null){
previousItems=newShoppingCart(...);
}
StringitemID=request.getParameter("itemID");
previousItems.addEntry(Catalog.getEntry(itemID));
session.putValue("previousItems",previousItems);
10.3实例:显现会话信息
上面这个例子天生一个Web页面,并在该页面中显现有关以后会话的信息。
packagehall;
importjava.io.*;
importjavax.servlet.*;
importjavax.servlet.http.*;
importjava.net.*;
importjava.util.*;
publicclassShowSessionextendsHttpServlet{
publicvoiddoGet(HttpServletRequestrequest,
HttpServletResponseresponse)
throwsServletException,IOException{
HttpSessionsession=request.getSession(true);
response.setContentType("text/html");
PrintWriterout=response.getWriter();
Stringtitle="SearchingtheWeb";
Stringheading;
IntegeraccessCount=newInteger(0);;
if(session.isNew()){
heading="Welcome,Newcomer";
}else{
heading="WelcomeBack";
IntegeroldAccessCount=
//在ServletAPI2.2中利用getAttribute而不是getValue
(Integer)session.getValue("accessCount");
if(oldAccessCount!=null){
accessCount=
newInteger(oldAccessCount.intValue()+1);
}
}
//在ServletAPI2.2中利用putAttribute
session.putValue("accessCount",accessCount);
out.println(ServletUtilities.headWithTitle(title)+
"<BODYBGCOLOR=\"#FDF5E6\">\n"+
"<H1ALIGN=\"CENTER\">"+heading+"</H1>\n"+
"<H2>InformationonYourSession:</H2>\n"+
"<TABLEBORDER=1ALIGN=CENTER>\n"+
"<TRBGCOLOR=\"#FFAD00\">\n"+
"<TH>InfoType<TH>Value\n"+
"<TR>\n"+
"<TD>ID\n"+
"<TD>"+session.getId()+"\n"+
"<TR>\n"+
"<TD>CreationTime\n"+
"<TD>"+newDate(session.getCreationTime())+"\n"+
"<TR>\n"+
"<TD>TimeofLastAccess\n"+
"<TD>"+newDate(session.getLastAccessedTime())+"\n"+
"<TR>\n"+
"<TD>NumberofPreviousAccesses\n"+
"<TD>"+accessCount+"\n"+
"</TABLE>\n"+
"</BODY></HTML>");
}
publicvoiddoPost(HttpServletRequestrequest,
HttpServletResponseresponse)
throwsServletException,IOException{
doGet(request,response);
}
}
专门做了这个例子;而java的这个例子好像就是为了教学而写的,很多教学目的的例子是不考虑优化、性能的。 |
|