servletCookieAndSession

 

一、       Introduction

Web的本质是两端数据的交互,每一次数据交互的过程就像一次会话过程,交流过程。对于会话过程中产生的某些信息的记录,便于促进某些会话结果或者会话期间产生的业务的实现。在web中,数据库、request、servletContext都可以用来记录信息。数据库的存储属于持久化存储,比如,当用户进行网购时,需要根据用户登录的状态,来判断是否可以进入购物车操作,显然,使用数据库存储登录记录,就丧失了对于用户端状态的追踪,不具有实时性;而用request记录用户登录状态,由于request中的记录只在本次请求响应中有效,如果用户登录后,将这个登录信息存入request,当用户发起新的请求后,这个登录信息将失效,同样不能实现对用户端会话的追踪;如果采用servletContext来存储,由于servletContext为项目级别的存储容器,那么当用户登录状态改变时,则需要频频改变servletContext的信息,如果用户量庞大,将会导致低效和系统安全问题。Cookie和session,正是为了解决对于web中两端会话的追踪记录,而被使用的web技术。

二、       Cookie

作为一种会话跟踪技术,cookie的产生早于session,当以个用户请求连接到每个服务器,服务器就会给这个用户一个标识,这个标识就是cookie。当大量的用户访问服务器时,服务器可以通过cookie区分开用户。Cookie中还记录了很多其他信息。在联网的条件下,打开某个网页,在地址栏输入JavaScript:alert(document. cookie),就可以查看服务器端为用户设定的cookie。Cookie的实现,需要浏览器的支持,如果浏览器不支持cookie或者禁用cookie,那么cookie将失效。作为服务器端,可以通过servlet操作cookie。Java提供了Cookie类专门用于对cookie的设置。由于cookie的内容,是服务器提供提供的,那么,cookie的内容要在首次响应后传给客户端。

1.        JavaEE API

javax.servlet.http
Class Cookie

java.lang.Object

  javax.servlet.http.Cookie

All Implemented Interfaces:

Cloneable

public class Cookie

extends Object

implements Cloneable

Implements: Cloneable
创建一个 cookie,cookie是 servlet 发送到 Web 浏览器的少量信息,这些信息由浏览器保存,然后发送回服务器。cookie 的值可以唯一地标识客户端,因此 cookie 常用于会话管理。

一个 cookie 拥有一个名称、一个值和一些可选属性,比如注释、路径和域限定符、最大生存时间和版本号。一些 Web 浏览器在处理可选属性方面存在 bug,因此有节制地使用这些属性可提高 servlet 的互操作性。

servlet 通过使用 HttpServletResponse#addCookie方法将 cookie 发送到浏览器,该方法将字段添加到HTTP 响应头,以便一次一个地将 cookie 发送到浏览器。浏览器应该支持每台 Web 服务器有 20 个cookie,总共有 300 个 cookie,并且可能将每个 cookie 的大小限定为 4 KB。

浏览器通过向 HTTP 请求头添加字段将 cookie 返回给 servlet。可使用 HttpServletRequest#getCookies方法从请求中获取 cookie。一些 cookie 可能有相同的名称,但却有不同的路径属性。

cookie 影响使用它们的 Web 页面的缓存。HTTP 1.0 不会缓存那些使用通过此类创建的 cookie 的页面。此类不支持 HTTP 1.1 中定义的缓存控件。

此类支持版本 0(遵守 Netscape 协议)和版本 1(遵守 RFC 2109 协议)cookie规范。默认情况下,cookie 是使用版本 0 创建的,以确保最佳互操作性。

2.        创建cookie

Cookie由服务器在服务器响应成功后产生,所以,cookie通过response对象传送到客户端。当第一次响应给客户端时,客户端程序,即浏览器中会保存这个cookie,同时,在浏览器的响应头中生成cookie信息,但是由于这是第一次请求发出时,所以,请求头中并没有cookie信息。而,当第一次之后的请求时,如果没有删除cookie,如果没有关闭页面或浏览器,那么,请求头中会加入cookie信息。关于这个情况,在不同的浏览器下,会有所差异。

 void

addCookie(Cookie cookie)
          Adds the specified cookie to the response.

1)        创建cookie对象;

2)        将cookie响应给客户端;

   protected voiddoGet(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {

      Cookie cookie1=new Cookie("c1","hahah");

      response.addCookie(cookie1);

      response.getWriter().write("addCookieToClient,pleaseCheck");

   }

3.       设置中文字符的cookie内容的编码与解码

      Cookie cookie=new Cookie("username",URLEncoder.encode("使用utf-8对中文编码","utf-8"));

      Cookie[] cookies=request.getCookies();

      for(Cookie c:cookies){

         if("username".equals(c.getName())){

            String decode=URLDecoder.decode(c.getValue(),"utf-8");

            System.out.println("解码后的cookie的值"+decode);

         }

      }

4.       获取客户端cookie信息

那么,客户端的cookie既然是存放在请求头中,那么通过request对象可以获得cookie信息。注意判断,request中cookie为空的情况。

Request对象的方法

 Cookie[]

getCookies()
          Returns an array containing all of the Cookie objects the client sent with this request.

Cookie类中的方法

 String

getName()
          Returns the name of the cookie.

 String

getValue()
          Returns the value of the cookie.

 void

setValue(String newValue)
          Assigns a new value to a cookie after the cookie is created.

例子:

   protected voiddoGet(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {

      Cookie cookie1=new Cookie("c1","hahah");

      Cookie cookies[]=request.getCookies();

      if(cookies!=null){

         for(Cookie cookie2:cookies){

            String cc=cookie2.getName();

            String cv=cookie2.getValue();

            System.out.println(cc+"--"+cv);

         }

      }

      response.addCookie(cookie1);

      response.getWriter().write("addCookieToClient,pleaseCheck");

   }

5.       设置cookie的生存时间

一般情况,cookie是临时性的,随着浏览器的关闭而清除。Cookie类中提供了设置cookie存活时间的方法。

 void

setMaxAge(int expiry)
          Sets the maximum age of the cookie in seconds.

其中的参数int expiry,以秒为单位,负数表示不存储cookie,浏览器关闭则消失;0表示立即清除cookie;正数表示持续存在多长时间,如60*60,即一个小时。

      Cookie cookieCycle=new Cookie("shengming","haha");

      //设置cookie的存活时间为6分钟

      cookieCycle.setMaxAge(6*60);

      response.addCookie(cookieCycle);

6.       设置cookie的响应路径

在响应对象添加cookie之前,可以给cookie设置响应成功后请求头可携带cookie的请求路径。Cookie的路径可以设置为其他项目或其子目录。

通过cookie对于转发,重定向的测试,得到一个现象,转发一般是多次请求,而重定向则只有一次请求,这也体现了转发能够将请求源贯穿到连续请求的情况。

1)       如果没有设置cookie的路径,那么当前cookie创建添加的目录及其子目录都可以使用。

2)       如果设置了cookie的路径,则设置cookie的路径目录及其子目录都可以使用。

3)       如果设置cookie的路径为其他项目,则本项目将访问服务端,将不能携带这个cookie。

4)       如果设置cookie的路径为/,则所有的以服务器ip:端口号开头的下的url路径都可以携带这个cookie。

例子:

      //cookieCycle.setPath("/spring/haha");

      cookieCycle.setPath("/");

7.       删除cookie

删除cookie,一般是将cookie的存活时间设为0,访问路径设为/,然后把这个设置后的cookie添加到服务器的响应对象。

      Cookie cookieCycle=new Cookie("shengming","haha");

      //设置cookie的存活时间为6分钟

      cookieCycle.setMaxAge(0);

      cookieCycle.setPath("/");

      response.addCookie(cookieCycle);

三、       Session

Cookie使用http协议在web交互中传播,存在被截获的可能,有安全隐患。即使设置了cookie的secure属性,仍然不能保证绝对安全。虽然,在服务端发放cookie时采用加密的方式,可以提高安全性,但对于机密度很高的数据,仍然不够安全。保证用户交互数据相对安全的手段,是将这些数据存放在服务端,一方面减少了这些数据在web中传播,另一方面,一般服务端的安全性相对较高。但是,由于session保存在服务器,使用session增加了服务器的压力。在session与客户端的交互中,需要借助cookie技术传递用户的唯一标识id。在java中,使用HttpSession接口可以操作session。

1.        JavaEE API

javax.servlet.http
Interface HttpSession

public interface HttpSession
提供一种方式,跨多个页面请求或对 Web 站点的多次访问标识用户并存储有关该用户的信息。

servlet 容器使用此接口创建HTTP 客户端和 HTTP 服务器之间的会话。会话将保留指定的时间段,跨多个连接或来自用户的页面请求。一个会话通常对应于一个用户,该用户可能多次访问一个站点。服务器能够以多种方式维护会话,比如使用 cookie 或重写 URL。

此接口允许 servlet

查看和操作有关某个会话的信息,比如会话标识符、创建时间和最后一次访问时间

将对象绑定到会话,允许跨多个用户连接保留用户信息

当应用程序将对象存储到会话中或从会话中移除对象时,该会话将检查对象是否实现了 HttpSessionBindingListener。如果实现了,则 servlet 将通知该对象它已经被绑定到会话,或者已从会话中取消对它的绑定。通知是在绑定方法完成后发送的。对于无效或过期的会话,通知是在会话已经无效或过期之后发送的。

当容器使用分布式容器设置在 VM 之间迁移会话时,所有实现 HttpSessionActivationListener接口的会话属性都会得到通知。

servlet 应该能够处理客户端选择不加入会话的情况,比如故意关闭 cookie 时。在客户端加入会话前,isNew 一直返回 true。如果客户端选择不加入会话,则 getSession 将对每个请求返回一个不同的会话,并且 isNew 将总是返回 true。

会话信息的范围仅限于当前 Web 应用程序(ServletContext),因此存储在一个上下文中的信息在另一个上下文中不是直接可见的。

2.       获取session及为session赋值

Session由服务器创建,当用户请求服务器时,通过request对象可以获取这个session。

Request的方法

 HttpSession

getSession()
          Returns the current session associated with this request, or if the request does not have a session, creates one.

 HttpSession

getSession(boolean create)
          Returns the current HttpSession associated with this request or, if there is no current session and create is true, returns a new session.

注意getSession(Boolean create)方法的含义。当参数为true时,如果没有session,则需要服务器创建一个session,如果为false或者使用了getSession,则不会创建了,那么返回的结果为null。

HttpSession的方法

 void

setAttribute(String name, Object value)
          Binds an object to this session, using the name specified.

 void

removeAttribute(String name)
          Removes the object bound with the specified name from this session.

 Object

getAttribute(String name)
          Returns the object bound with the specified name in this session, or null if no object is bound under the name.

例子:

   protected voiddoGet(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {

      HttpSession session=request.getSession();

      //将键值对放入session

      session.setAttribute("haha", request.getRemoteAddr());

   }

   protected voiddoGet(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {

      String haha=(String)request.getSession().getAttribute("haha");

      response.getWriter().write(haha);

   }

3.       Session的生命周期

Session作为跟踪客户端会话的技术,在区别不同的客户端方面,采用cookie技术存放一个唯一标识,所以,服务器取得客户端的session需要借助cookie。然后,cookie的存在有3中情况,1,随浏览器关闭清除,2,根据设置的时效清除,3,立即清除。所以,如果,关闭浏览器cookie清除,则无法获得这个客户端的session。通过持久化cookie,可以持久化session,前提是没有对session使用invalidate方法。

Session的创建时间:在服务器开启的前提下,客户端首次访问服务器时,通过servlet的getSession方法,服务器得到信号,就会创建这个客户端的session容器。

Session的销毁时间:A,非正常关闭服务器。在正常关闭服务器的时候,session会保存在服务器的某个文件中。

B,为了防止内存溢出,一般情况下,服务器会将不常活跃的session设置一个超时时间,超过一定时间没有访问服务器,则session失效。Session的超时时间可以通过setMaxInactiveInterval方法修改。也可以在web.xml中配置。C,调用session的invalidate方法同样可以使session失效。

 void

setMaxInactiveInterval(int interval)
          Specifies the time, in seconds, between client requests before the servlet container will invalidate this session.

setMaxInactiveInterval方法中参数的单位为秒。

Web.xml配置session有效期的例子:

  <session-config>

      <!-- 参数的单位为分钟 -->

      <session-timeout>3</session-timeout>

  </session-config>

四、       关于servlet存放数据的容器

ServletContext:项目下所有servlet共享,不具有针对性。

ServletSession:针对某个客户端的容器对象。适合客户端使用服务器服务期间的业务需求。

HttpServletRequest:针对客户端的某次请求,响应结束,这容器清空。适合请求期间的数据传输需求。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值