会话及其会话技术




会话概述




指的是一个客户端(浏览器)与Web服务器之间连续发生的一系列请求和响应过程。



会话:从浏览器开启到浏览器关闭。会话技术:用来保存在会话期间 浏览器和服务器所产生的数据。

在Servlet技术中,提供了两个用于保存会话数据的对象,分别是Cookie和Session。



Cookie对象




什么是Cookie




服务器和客户端之间传递的一张小纸条,cookie就是用来传递和存储数据。

    cookie由服务器端写的, cookie由客户端保存的。

    cookie由响应头  Set-Cookie:k1=v1; path=  形式传递给浏览器

    cookie由请求头  Cookie:k1=v1; k2=v2; k3=v3; ...形式传递给服务器


在Web应用中当用户通过浏览器访问Web服务器时,服务器会给客户发送一些信息,这些信息都保存在Cookie中。这样,当该浏览器再次访问服务器时,都会在请求头中将Cookie发送给服务器,方便服务器对浏览器做出正确的响应。

服务器向客户端发送Cookie时,会在HTTP响应头字段中增加Set-Cookie响应头字段。Set-Cookie头字段中设置的Cookie遵循一定的语法格式,具体示例如下:

Set-Cookie: user=itcast; Path=/;


在HttpServletResponse接口中定义了一个addCookie方法来向浏览器发送Cookie消息(也就是Cookie对象),在HttpServletRequest接口中定义了一个getCookies方法来读取浏览器发送的Web服务器的所有Cookie消息。Cookie类中定义了生成和提取Cookie消息的各个属性的方法。



添加cookie 的方式




 1.Cookie c = new Cookie("uname",URLEncoder.encode("小陈", "utf-8"));

    response.addCookie(c);

    Cookie的value不能有中文,需要使用URL对中文进行编码。

 2.response.addHeader("Set-Cookie","uname1=xiaochen")

    //把cookie追加到响应头上

    response.stHeader("Set-Cookie","uname1=xiaochen")

    //设置头字段



Cookie操作




为了封装Cookie信息,在Servlet API中提供了一个javax.servlet.http.Cookie类,该类包含了生成Cookie信息和提取Cookie信息各个属性的方法。


1、构造方法

   Cookie类有且仅有一个构造方法,具体语法格式如下:

public Cookie(java.lang.String name,java.lang.String value)

需要注意的是,Cookie一旦创建,它的名称就不能更改,Cookie的值可以为任何值,创建后允许被修改。


2、Cookie类的常用方法

setMaxAge(int expiry)和getMaxAge()方法

上面的这两个方法用于设置和返回Cookie在浏览器上保持有效的秒数。

如果设置的值为一个正整数时,浏览器会将Cookie信息保存在本地硬盘中。从当前时间开始,在没有超过指定的秒数之前,这个Cookie都保持有效,并且同一台计算机上运行的该浏览器都可以使用这个Cookie信息。

如果设置值为负整数时,浏览器会将Cookie信息保存在的缓存中,当浏览器关闭时,Cookie信息会被删除。

如果设置值为0时,则表示通知浏览器立即删除这个Cookie信息。

默认情况下,Max-Age属性的值是-1。




setPath(String uri)和getPath()方法



上面的这两个方法是针对Cookie的Path属性的。

如果创建的某个Cookie对象没有设置Path属性,那么该Cookie只对当前访问路径所属的目录及其子目录有效。

如果想让某个Cookie项对站点的所有目录下的访问路径都有效,应调用Cookie对象的setPath()方法将其Path属性设置为“/”。



setDomain(String pattern)和getDomain()方法



上面的这两个方法是针对Cookie的Domain属性的。

Domain属性是用来指定浏览器访问的域。例如,传智播客的域为“itcast.cn”。那么,当设置Domain属性时,其值必须以“.”开头,如Domain=.itcast.cn。

默认情况下,Domain属性的值为当前主机名,浏览器在访问当前主机下的资源时,都会将Cookie信息回送给服务器。需要注意的是,Domain属性的值是不区分大小写的。



其他常用方法




    getName方法 用于获得Cookie的名称

    setValue和getValue方法 分别用于设置和获得Cookie的值

    setMaxAge和getMaxAge方法 分别用于设置和获得Cookie在客户机的有效时间,也就是在在客户机上的有效秒数

    setPath和getPath方法 分别用于设置和获得当前Cookie的有效Web路径

    setDomain和getDomain方法 分别用于设置和获得当前Cookie的有效域

    setComment和getComment方法 分别用于设置和返回当前Cookie的注释部分

    setVersion与getVersion方法 分别用于设置和获得当前Cookie的协议版本

    setSecure和getSecure方法 分别用于设置和获得当前Cookie是否只能使用安全的协议传输Cookie




Cookie的持久化




1.持久化:就是把数据从内存中写到硬盘上

    cookie默认是在浏览器缓存中【内存中】

    cookie通过持久化设置,可以保存在硬盘上。

2.设置方法:

    cookie.setMaxAge(int sec);      设置cookie最大生存时间,单位为秒

    -1    保存在浏览器缓存中。 【默认,不需要设置】

    >0    保存到浏览器的硬盘上。  【保存位置由各个浏览器自己制定】

     0     cookie立刻过期。删除一个cookie

    已经过期的cookie 浏览器是不会传递。



cookie的唯一性标识:


cookie   -http 域名  -path路径  -cookie的name   相同时,cookie才相同。

实例1:域名不同,有效路径相同,cookie的name相同,  不是一个cookie,分开保存

cookie1: k1=v1   http://192.168.113.11/WEB16/

cookie2: k1=v1 http://192.168.113.111/WEB16/


实例2:域名相同,有效路径不同,cookie的name相同,  不是一个cookie,分开保存

cookie1: k1=v1   http://192.168.113.111/WEB15/

cookie2: k1=v1 http://192.168.113.111/WEB16/


实例3:域名相同,有效路径相同,cookie的name不同,  不是一个cookie,分开保存

cookie1: k1=v1   http://192.168.113.111/WEB16/

cookie2: k2=v1 http://192.168.113.111/WEB16/


实例4:域名相同,有效路径相同,cookie的name相同,  是一个cookie,新cookie覆盖老cookie

cookie1: k1=v1   http://192.168.113.111/WEB16/

cookie2: k1=v1 http://192.168.113.111/WEB16/




cookie使用有注意事项




cookie不支持直接存中文。    【URL编码编码中文】

【用URLEncoder编辑,保存cookie】【用URLDecoder解码,取出cookie值】

cookie并不是javaEE独有的,而是由HTTP协议指定的,只要遵循HTTP协议,都可以用cookie技术



Cookie的value是有长度限制的,4KB。   【建议cookie都是存短少数据,一般都是标识】

一个浏览器接收的cookie也是有上限。300个  【为了保证程序效率,尽量经常清cookie】

一个网站存储的cookie也是有上限的。30个    【cookie使用的时候要慎重,不要写太多个】



Session对象




什么是Session




session对象用来保存每个用户的用户信息和会话状态。session对象由服务器端自动创建,可以跟踪每个用户的操作状态。

用户首次登录系统时服务器会自动给用户分配唯一标识的session id,可以用来区分开其他用户。相对于Cookie,session是存储在服务器端的会话,相对安全,而且其存储长度限制也大大的扩大了。




session概述



session保存在服务端的会话技术      域对象,MAP

其它域对象:ServletContext,session,request

这个域对象 仅对当前的会话有效!!!不能跨浏览器。


原理


session实现依赖于cookie【会话级别】,将JSESSIONID存入Cookie中。

会话关闭了,cookie被销毁,sessionid丢失,但是session并没有销毁。




HttpSession API




在Servlet中使用HttpSession对象来描述Session。一个HttpSession对象就是一个Session。使用HttpServletRequest接口的getSession方法来获得一个HttpSession对象。

Session是与每个请求消息紧密相关的,为此HttpServletRequest定义了用于获取Session对象的getSession()方法,该方法有两种重载形式,具体如下:

    public HttpSession getSession(boolean create)

    public HttpSession getSession()

上面重载的两个方法都用于返回与当前请求相关的HttpSession对象。



    public HttpSession getSession(boolean create)

该方法根据传递的参数来判断是否创建新的HttpSession对象,如果参数为true,则在相关的HttpSession对象不存在时创建并返回新的HttpSession对象,否则不创建新的HttpSession对象,而是返回null。



    public HttpSession getSession()

该方法则相当于上一个方法参数为true时的情况,在相关的HttpSession对象不存在时总是创建新的HttpSession对象。

需要注意的是,由于getSession()方法可能会产生发送会话标识号的Cookie头字段,因此必须在发送任何响应内容之前调用getSession()方法

    getId方法 用于返回当前HttpSession对象的SessionID

    getCreationTime方法 用于返回当前的HttpSession对象的创建时间

    getLastAccessedTime方法 用于返回当前HttpSession对象的上一次被访问的时间

    setMaxInactiveInterval和

    getMaxInactiveInterval方法 分别用来设置和返回当前HttpSession对象的可空闲的最长时间(单位:秒),这个时间也就是当前会话的有效间隔

    isNew方法 用来判断当前的HttpSession对象是否是新创建的,如果是则返回true,否则返回false

    isvalidate方法 用于强制当前的HttpSession对象失效,这样Web服务器可以立即释放该HttpSession对象

    getServletContext方法 用于返回当前HttpSession对象所属的Web应用程序的ServletContext对象

    setAttribute方法 用于将一个String类型的ID和一个对象相关联,并将其保存在当前的HttpSession对象中

    getAttribute方法 用于返回一个和String类型的ID相关联的对象

    remoteAttribute方法 用于删除与一个String类型的ID相关联的对象




Session超时管理




Web服务器采用了“超时限制”的办法来判断客户端是否还在继续访问。在一定时间内,如果某个客户端一直没有请求访问,那么,Web服务器就会认为该客户端已经结束请求,并且将与该客户端会话所对应的HttpSession对象变成垃圾对象,等待垃圾收集器将其从内存中彻底清除。


反之,如果浏览器超时后,再次向服务器发出请求访问,那么,Web服务器则会创建一个新的HttpSession对象,并为其分配一个新的ID属性。


在会话过程中,会话的有效时间可以在web.xml文件中设置,其默认值由Servlet容器定义。在<tomcat安装目录>\conf\web.xml文件中,可以找到如下一段配置信息:

<session-config>

    <session-timeout>30</session-timeout>

</session-config>

以分钟为单位

如果将<session-timeout>元素中的时间值设置成0或一个负数,则表示会话永不超时。



由于<tomcat安装目录>\conf\web.xml文件对站点内的所有Web应用程序都起作用,因此,如果想单独设置某个Web应用程序的会话超时间隔,则需要在自己应用的web.xml文件中进行设置。

需要注意的是,要想使Session失效,除了可以等待会话时间超时外,还可以通过invalidate()方法强制使会话失效。




通过Cookie跟踪Session




客户端必须通过一个SessionID才能找到以前在服务端创建的某一个HttpSession对象。通过SessionID找HttpSession对象的过程也叫做Session跟踪。


一般客户端的SessionID通过HTTP请求消息头的Cookie字段发送给服务端,然后服务端通过getSession方法读取Cookie字段的值,以确定是否需要新建一个HttpSession对象,还是获得一个已经存在的HttpSession对象,或是什么都不做,直接返回null。


当HttpSession对象是第一次创建时,向这个对象中写一个字符串值。如果HttpSession对象不是第一次创建,那么就将保存在HttpSession对象中的字符串值输出到客户端




通过重写URL跟踪Session




如果客户端浏览器不支持Cookie或是将Cookie功能关闭,那么就无法使用Cookie来传递SessionID。为了在这种情况下仍然可以使用Session,Servlet规范提供了一种补充会话管理机制。这种管理机制允许在Cookie无法工作的情况下使用URL参数来传递SessionID。



要想通过URL来发送SessionID,必须要重写URL。HttpServletResponse提供了两个方法用于重写URL

    encodeURL方法  用于对所有内嵌在Servlet中的URL进行重写

    encodeRedirect方法  用于对sendRedirect方法所使用的URL进行重写