JAVA WEB开发中的会话跟踪

时间:2024-07-29 15:37:44

  常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。

  Http协议是一种无状态的协议,一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接,这就意味着服务器无法从连接上跟踪会话,可以使用Cookie和Session来跟踪会话。

  Cookie

  Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。

  Cookie的功能需要浏览器的支持。如果浏览器不支持(如大部分的手机浏览器)或者把Cookie禁用了,Cookie功能就会失效。

  Cookie封装成了javax.servlet.http.Cookie类。可以通过request.getCookie()获取到所有Cookie的一个数组。

  Cookie中只能存ASCII字符,所以对中文,二进制数据等要进行处理,对于中文,可以使用java.net.URLEncoder类的encode(String str, String encoding)方法进行编码,使用java.net.URLDecoder类的decode(String str, String encoding)方法进行解码;对于二进制数据如图片,可以使用BASE64编解码。BASE64Encoder.class.newInstance().encode(byte[]), BASE64Decoder.class.newInstance().decodeBuffer(String)

  Cookie的属性

  对应的有get,set方法

  name名, value值, maxAge失效时间, secure是否仅被安全协议传输, path可以访问的路径, domain呆以访问的域名, comment用处说明, version使用的版本。

  Cookie的有效期

  Cookie的maxAge决定着Cookie的有效期,单位为秒。通过getMaxAge()与setMaxAge(int)来读写maxAge属性。

  如果maxAge为正数,则Cookie将在maxAge秒之后失效,如下面的例子Cookie将永远有效。

  cookie.setMaxAge(Integer.MAX_VALUE);

  如果maxAge为负数,则表示该Cookie仅在本浏览器窗口以及本窗口打开的子窗口内有效,关闭窗口后该Cookie即失效。maxAge为负数的Cookie,为临时性Cookie,不会被持久化,不会被写到Cookie文件中。Cookie信息保存在浏览器内存中,因为关闭浏览器该Cookie就消失了。Cookie默认的maxAge为-1。

  如果maxAge为0,则表示删除该Cookie。是采用失效实现删除Cookie的效果。失效的Cookie会被浏览器从Cookie文件或者内存中删除。

  response对象提供的Cookie操作方法只有一个添加操作add(Cookie cookie)。要想修改Cookie只能使用一个同名的Cookie来覆盖原来的Cookie,达到修改的目的。删除时只需要把maxAge修改为0即可。

  Cookie的域名

  Cookie是不可跨域名的。但可以通过设置domain属性使一组域名可以共享同一个Cookie。如下面的例子:

  cookie.setDomain(".helloweenvsfei.com");

  domain参数必须以点(".")开始。

  Cookie的路径

  domain属性决定运行访问Cookie的域名,而path属性决定允许访问Cookie的路径,粒度比domain要细。

  Cookie的安全属性

  HTTP协议不仅是无状态的,而且是不安全的。使用HTTP协议的数据不经过任何加密就直接在网络上传播,有被截获的可能。使用HTTP协议转输很机密的内容是一种隐患。如果不希望Cookie在HTTP等非安全协议中传输,可以设置Cookie的secure属性为true。浏览器只会在HTTPS和SSL等安全协议中传输此类Cookie。下面的代码设置secure属性为true:

  cookie.setSecure(true);

  但请注意secure属性并不能对Cookie内容加密,因而不能保证绝对的安全性。如果需要高安全性,需要在程序中对Cookie内容加密、解密,以防泄密。

  JAVASCRIPT操作Cookie

  Cookie是保存在浏览器端的,因此浏览器具有操作Cookie的先决条件。浏览器可以使用脚本程序如JavaScript或者VBScript等操作Cookie。

  document.cookie获取Cookie字符串

  具体获取某个Cookie的方法请自行通过网络获取,JavaScript中并没有专门处理Cookie的API。

  Session

  Session是服务端使用的一种记录客户端状态的机制,使用上比Cookie简单一些,相应的也增加了服务器的存储压力。

  什么是Session

  Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。

  如果说Cookie机制是通过检查客户身上的“通行证“来确定客户身份的话,那么Session机制就是通过检查服务器上的”客户明细表“来确认客户身份。Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案就可以了。

  Session对应的类为javax.servlet.http.HttpSession。每个来访者对应一个Session对象,所有该对象的状态信息都保存在这个Session里。Session是在客户端第一次请求服务器的时候创建的。设置,获取的方法为setAttribute(String, String),getAttribute(String),通过request.getSession()方法获取该客户的Session,还有一个重载方法request.getSession(boolean),如果为true,当session不存在时,该方法会先创建Session再将Session返回,而getSession()在不存在Session时会返回null。

  Session与Cookie的一个重要区别是Cookie只能保存字符串,而Session可以保存一切对象,类,基本类型等。

  Session的生命周期

  Session保存在服务器端。一般在内存中,所以当Session过多,内容过于复杂时,会对服务器造成很大的压力。Session在用户第一次访问服务器的时候自动创建,这里只有访问JSP、Servlet等程序时才会创建Session,访问HTML、IMAGE等静态资源并不会创建Session。Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。用户每访问一次服务器,无论是否读写Session,服务器都认为该用户的Session”活跃“了一次。

  Session的有效期

  Session的超时时间为maxInactiveInterval属性,可以通过对应的getMaxInactiveInterval()获取,通过setMaxInactiveInterval(long)修改。Session的超时时间也可以在web.xml中修改,具体方法自行找相关资料。另外,通过调用invalidate()方法可以使Session失效。

  Session的常用方法

  setAttribute(String, Object)

  getAttribute(String)

  getAttributeNames()

  removeAttribute(String)

  getId()

  getCreationTime()

  getLastAccessedTime()

  getMaxInactiveInterval()

  setMaxInactiveInterval(int)

  putValue(String, Object)

  getValue(String)

  isNew()

  invalidate()

  Tomcat中Session的默认超时时间为20分钟。通过setMaxInactiveInterval(int)修改超时间间。

  Session对浏览器的要求

  服务器会向客户端浏览器发送一个名为JSESSIONID的Cookie,它的值为该Session的id,Session依据该Cookie来识别是否为同一用户。如果客户端浏览器将Cookie功能禁用,或者不支持Cookie怎么办?答案是URL地址重写。

  URL地址重写

  原理是将该用户的Session的id重写到URL地址中。服务器能够解析重写后的URL获取Session的id。这样即使客户端不支持Cookie,也可以使用Session来记录用户状态。HttpServletResponse类提供了encodeURL(String),encodeRedirectURL(String)实现URL地址重写。

  Session中禁止使用Cookie

  在WebRoot目录下的META-INF文件夹下创建context.xml,内容如下:

  <?xml version='1.0' encoding='UTF-8' ?>

  <Context path="/sessionWeb" cookies="false">

  </Context>

  或者修改Tomcat全局的conf/context.xml,修改内容如下:

  <Context cookies="false">

   ...

  </Context>

  这样TOMCAT便不会自动生成名JSESSIONID的Cookie,Session也不坐以Cookie为识别标志,而仅仅以重写后的URL地址为识别标志了。

  注意该配置只是禁止Session使用Cookie作为识别标志,并不能阻止其他的Cookie读写。也就是说服务器不会自动维护名为JSESSIONID的Cookie了,但是程序中仍然可以读写其他的Cookie。

  Session与Cookie的比较

  1. 存取方式

  Cookie:ASCII字符串,如果需要存取Unicode字符或者二进制数据,需要进行UTF-8,GBK或者BASE64编码。

  Session:可以存取任何类型的数据,可以把Session看做是一个Java容器类。

  2. 隐私安全

  Cookie:存储在客户端,不安全,如果使用Cookie,敏感信息如账号密码等尽量不要写到Cookie中,Cookie中的信息进行加密,到服务器后再进行解密。

  Session:存储在服务器,安全。

  3. 有效期

  Cookie:可以长久记录信息,只要把maxAge设置成一个很大的数。

  Session:不利于长久记录信息,因为Session依赖于名为JSESSIONID的Cookie,而Cookie JSESSIONID的maxAge默认为-1,只要关闭了浏览器该Session就会失效,因此Session不能实现信息长久有效的效果。使用URL地址重写也不能实现。而且如果设置Session的超时时间过长,服务器累计的Session就会越多,越容易导致内存溢出。

  4. 服务器负担

  Cookie:保存在客户端浏览器,不占用服务器资源。

  Session:保存在服务器端,如果并发访问的用户非常多,会产生非常多的Session,消耗大量的内存。

  5. 浏览器支持

  Cookie:需要客户端浏览器的支持,如果被禁用或是不支持,就无法使用,而对于WAP应用,常规的Cookie就不支持。如果浏览器支持Cookie,既可以设为本浏览器窗口以及子窗口内有效(maxAge=-1),也可以设为所有浏览器窗口内有效(maxAge设为某个大于0的整数)。

  Session:只能在本窗口及子窗口内有效。如果两个浏览器窗口互不相干,它们将使用两个不同的Session。

  6. 跨域名

  Cookie:通过设置domain属性来支持跨域名。

  Session:不能跨域名。

  小结

  Cookie是早期的会话跟踪技术,它将信息保存到客户端浏览器中。浏览器访问网站时会携带这些Cookie信息,达到鉴别身份的目的。

  Session是在Cookie基础上建立的会话跟踪技术,它将信息保存在服务器端,Session中能够存储不同的JAVA对象,因此使用更加方便。Session依赖于名为JSESSIONID的Cookie.

  如果客户端浏览器不支持Cookie,或者禁用了Cookie,仍然可以通过使用URL地址重写来使用Session。