2.1 网址重写
网址重写是一种Session追踪技术,需要将一个或多个token做为一个查询字符串添加到一个URL中。Token的格式一般是键=值。
Url?key-1=value-1&key-2=value-2...&key-n=value-n
2.2 隐藏域
利用隐藏域来保持状态,与采用网址重写技术类似。但它不是将值添加到URL后面,而是将他们放在HTML表单的隐藏域中。当用户提交表单时,隐藏域的值也传送到服务器。只有当页面包含表单,或者可以在页面中添加表单时,才适合使用隐藏域。这种技术胜过网址重写的地方在于,可以将更多的字符传到服务器,并且不需要进行字符编码。但是像网址重写一样,也只有当要传递的信息不需要跨越多个页面时,才适合使用这种技术。常见的隐藏域我们用来显示id,这样方便编辑的时候可以根据id获取到值显示出来。
2.3 Cookie
Cookie是自动在Web服务器和浏览器之间来回传递的一小块信息。Cookie适用于那些需要跨越许多页面的信息。由于cookie是做为HTTP标头嵌入的,因此传输他的过程由HTTP协议处理。除此之外,还可以根据自己的需要设置cookie的有效期限。对于Web浏览器而言,每台Web服务器最多可以支持20额cookie。
Cookie的不足之处在于,用户可以通过修改他的浏览器设置来拒绝接受cookie。
要使用cookie,必须熟悉javax.servlet.http.cookie类,以及HttpServletRequest和HttpServletResponse接口中的几个方法。
要创建一个cookie,传递一个名称和一个值给Cookie类的构造器:
Cookie cookie = new Cookie(name,value) ;
例如,要创建一个选择语言的cookie,可以这么写:
Cookie languageSelectionCookie = new Cookie(“language”,”Italian”) ;
创建cookie之后,可以设置他的domain、path及maxAge属性。尤其值得关注的是maxAge属性,因为它决定cookie的有效期。
httpservletResponse.addCookie(cookie);
当浏览器再次发出对同一个资源或者对同一台服务器中的不通资源的请求时,它会同时把从Web浏览器处收到的cookie再传回去。
要访问浏览器发出的cookie,可以在HttpServletRequest中使用getCookies方法。该方法将返回一个Cookie数组,如果请求中没有cookie,将返回null。为了找到某个名称的cookie,需要迭代数组。下面举个例子,看看如何读取一个名为maxRecords的cookie。
令人遗憾的是,没有getCookieByName方法可以使获取cookie变得更简单一些。更令人难过的是,也没有方法可以直接删除cookie。为了删除cookie,需要创建一个同名的cookie,将它的maxAge属性设置为0,并在HttpServletResponse中添加一个新的cookie。看看下面是如何删除一个名为userName的cookie的:
Cookie cookie = new Cookie(“userName”,””) ;
cookie.setMaxAge(0) ;
response.addCookie(cookie) ;
2.4 HttpSession对象
HttpSession是当一个用户第一次访问某个网站时自动创建的。通过在HttpServletRequest中调用getSession方法,可以获取用户的HttpSession。getSession有两个重载方法:
HttpSession getSession()
HttpSession getSession(boolean create)
无参的getSession方法返回当前的HttpSession,如果当前没有,则创建一个并返回。getSession(false)方法返回当前的HttpSession(若有),如果没有,则返回null。getSession(true)方法返回当前的HttpSession(若有),如果没有,则新建一个并返回。getSession(true)和getSession是一样的。
放在HttpSession中的值是保存在内存中的。
添加到HttpSession中的值不一定是String,可以为任意Java对象,只要它的类实现了java.io.Serializable接口即可,以便当Servlet容器认为有必要的时候,保存的对象可以序列化成一个文件或者保存到数据库中,例如,当容器的内存快要用完的时候,仍然可以将非序列化的对象保存在HttpSession中,但是如果Servlet容器试图将他们序列化,将会以失败告终,并抛出异常。
通过在HttpSession中调用getAttribute方法,同时传递一个属性名称,可以获取HttpSession中保存的对象。这个方法的签名如下:
java.lang.Object getAttribute(java.lang.String name)
HttpSession中另一个有用的方法是getAttributeNames,它返回一个Enumeration,迭代一个HttpSession中的所有属性:
java.util.Enumeration<java.lang.String> getAttributeNames()
注意,HttpSession中保存的值不发送到客户端,这与其他的Session管理方法不同。而是servlet容器为它所创建的每一个HttpSession生成一个唯一标识符,并将这个标识符做为一个token发送给浏览器,一般是做为一个名为JSESSIONID的cookie,或者做为一个jessionid参数添加到url后面。在后续的请求中,浏览器会将这个token发送回服务器,使服务器能够知道是哪个用户在发出请求。无论servlet容器选择用哪一种方式传输session标识符,那都是在后台自动完成的,不需要你去做额外的处理工作。
Java.lang.String getId()
HttpSession中还定义了一个invalidate方法。这个方法强制Session过期,并将绑定到它的所有对象都解除绑定。在默认情况下,HttpSession是在用户静默一定时间之后过期,可以在部署描述符的session-timeout元素中将session的期限设置为整个应用程序。例如,将这个值设为30,使所有session对象在用户最后一次访问之后30分钟过期。如果没有配置这个元素,这个期限将由servlet容器决定。
很多时候,还需要销毁未过期却又没用的HttpSession实例,以便释放一些内存空间。
可以调用getMaxInactiveInterval方法,以了解一个HttpSession在用户最后一次访问之后还可以维持多久。这个方法返回用户离开的秒数。setMaxInactiveInterval方法可以帮助你为个别HttpSession的Session期限设置一个不同的值。
Void setMaxInactiveInterval(int seconds)
如果向这个方法传递0,那么HttpSession将永远不会过期。一般来说,这不是一个好方法,因为HttpSession占用的堆(heap)空间将永远不会释放,直到应用程序卸载或Servlet容器关闭为止。