内容简介:Java Cookie和Session
1.会话技术简介
http协议是无状态的,因此对于服务端来说,当它接收到客户端的http请求时,无法识别这个请求来源于哪个客户端。无状态的协议有优点也有缺点,但对于需要识别客户端甚至是需要记住客户端的业务来说,应当要让http协议"有状态"。
需要记住客户端的业务种类非常多。例如登陆系统,在一个页面登录后,新打开一个该网站页面,应当也保持登录状态。再例如购物车系统,某用户添加商品1后应当保证他还能继续添加商品2,在结算时能够读取购物车中的所有商品。
如何让服务端记住客户端?目前使用最多的是cookie和session两种会话技术。
- 1. Cookie:数据存储在客户端本地,减少服务器端的存储的压力,安全性不好,客户端可以清除cookie。
- 2. Session:将数据存储到服务器端,安全性相对好,会增加服务器的压力。
2.Cookie技术
Cookie技术是 将用户的数据存储到客户端 的技术,它的作用是为了让服务端根据每个客户端持有的cookie来区分不同客户端。
cookie由cookie name、具有唯一性的cookie value以及一些属性(path、expires、domain等)构成,其中value是区分客户端的唯一依据。
Cookie的原理为: 服务端在接收到客户端首次发送的请求后,服务端在响应首部中加入"set-cookie"字段发送给客户端;客户端接收响应后,将cookie信息存储到内存中(如果设置了MaxAge属性,则存储到磁盘中);因为cookie数据在浏览器的内存中,因此无论是哪个页面,客户端再次向服务端发送请求时都能获取该cookie信息,并在请求首部中加入"cookie"字段发送给服务端;服务端借此就可以识别客户端,并从cookie中找到该客户端的信息。
使用Cookie需要解决的两个问题:
- (1).服务端怎样将一个Cookie发送到客户端。
- (2).服务端怎样接受客户端携带的Cookie。
2.1 服务器端向客户端发送Cookie
设置Cookie涉及的几个常用方法为:
-
Cookie(String cookie_name,String cookie_value)
:构造一个Cookie对象。 -
setPath(uri)
:当访问属于该uri下的路径(包括子路径)时,该cookie都生效,例如setPath("/Cookie")
,当本机使用http://localhost/Cookie/servlet1
和http://localhost/Cookie/servlet2
访问时,都拥有该Cookie。 -
setMaxAge(int second)
:设置该属性时,cookie将持久化保存到客户端的磁盘中,保存时间为second秒。如果cookie不具有该属性,则cookie只会存放在内存中。 -
setDomain(String domain)
:设置Cookie生效的域范围,例如cookie.setDomain(".foo.com");
,这将对foo.com域下的所有主机都生效(如www.foo.com),但不包括子域(www.abc.foo.com)。
设置好Cookie后,需要使用response的方法 addCookie(Cookie cookie)
将cookie加入到响应首部中发送给客户端。
例如,以下是名为CooikeDemo工程的一个servlet,该servlet的uri路径为"/cookieservlet"。
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class CookieServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cookie cookie = new Cookie("username","zhangsan"); //构造cookie对象 cookie.setPath("/CookieDemo"); //设置cookie生效的uri范围 cookie.setMaxAge(10*60); //设置cookie持久到磁盘的时间为10分钟 response.addCookie(cookie); //在响应首部中加入set-cookie字段并发送给客户端 } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }
该cookie将会在响应首部加入set-cookie字段发送给客户端:

当客户端再次请求时,将在请求首部中加入cookie字段。

需要注意的几点:
- (1).Cookie中不能存储中文。
- (2).如果不设置持久化时间,cookie会存储在浏览器的内存中,浏览器关闭时cookie信息销毁,这是会话级的cookie。如果设置持久化时间,cookie信息会被持久化到磁盘中,这是持久级别的cookie。持久化后的cookie不会随浏览器关闭而失效,而是在有效时间内都有效。
- (3).
setPath()
设置的生效路径为目录时,则cookie对该目录和子目录下的资源都生效,如果生效路径为文件时,则只对该文件有效。例如:cookie.setPath("/webapp"); //代表访问webapp应用中的任何资源都携带cookie cookie.setPath("/webapp/cookieservlet"); //代表访问webapp中的cookieservlet时才携带cookie信息
- (4).如果想要删除当前还有效的cookie信息,可以使用同名同路径的持久化时间为0的cookie进行覆盖。这样一来,每次客户端接收到响应后cookie就立即失效,也就无法携带cookie请求服务端。例如删除上面示例的cookie信息
Cookie cookie = new Cookie("username","zhangsan"); cookie.setPath("/CookieDemo"); cookie.setMaxAge(0); response.addCookie(cookie);
2.2 服务器端接受客户端携带的Cookie
如前面的图中所示,客户端的cookie信息是以请求头的方式发送到服务器端的。因此服务端要获取cookie信息,需要使用request对象中的方法 getCookies()
。这时唯一的获取cookie的方法,它返回的是Cookie数组集合,因此需要遍历该数组才能获取指定名称的cookie。
例如,获取cookie name为"username"的cookie。
Cookie[] cookies = request.getCookies(); if(cookies != null) { for (Cookie coo : cookies) { String cookie_name = coo.getName(); if (cookie_name.equals("username")) { String cookie_value = coo.getValue(); System.out.println(cookie_name+":"+cookie_value); } } }
3.Session技术
从打开一个浏览器访问某个站点,到关闭这个浏览器的整个过程(释放浏览器内存),成为一次会话。除了Cookie技术可以让服务端在一次会话过程中记住客户端,Session技术也可以达到这样的目的。
Session技术将数据存储在服务器端,它会为每个客户端都创建一块内存空间存储客户端数据,并为客户端分配一个存储在cookie中的JSESSIONID,客户端需要每次都携带一个这个ID,服务器通过这个ID可以找到属于该客户端的内存空间。由于这个标识ID是借助Cookie存储的唯一性标识JSESSIONID,因此Session是基于Cookie来实现的。
Session的原理: 服务端接收到某客户端首次发送的请求后,为此客户端生成一个session,并分配一段属于该session的缓冲区,同时将该session配对的标识号JSESSIONID作为cookie的name添加到响应首部中返回给客户端;客户端下次访问时,请求首部中将携带该JSESSIONID,服务端将根据该JSESSIONID寻找与之配对的session,如果能找到对应的session,则直接操作该session资源,否则将重新为此JSESSIONID分配一个session和对应的缓冲区。
使用Session技术需要解决如下三个问题:
- (1).怎样获得属于某客户端的session对象(内存区域)?
- (2).怎样向session中存取数据?
- (3).session对象的生命周期?
3.1 获得Session对象
服务端通过客户端发送cookie中的JSESSIONID区分客户端,可以通过请求包中的这个信息来获取该客户端相关的session信息。
HttpSession session = request.getSession();
此方法有两个作用:
- (1).从cookie中获取JSESSIONID,并寻找是否存在该ID对应的session对象。如果存在,则获取该session对象。
- (2).如果该客户端没有发送JSESSIONID或JSESSIONID和服务端记录的ID值不匹配,则为该JSESSIONID重新分配一个session对象。
实际上就是根据JSESSIONID判断该客户端是否在服务器上已经存在session了,有则用之,无则分配之。
3.2 向session中存取数据(session也是一个域对象)
session也是一个域对象,session域的作用范围是整个session,可以对客户端的多次请求生效。该范围小于context域(即application域),大于request域(只在一次请求内有效)。
作为域对象,session对象也同样具有如下三个方法:
session.setAttribute(String name,Object obj); session.getAttribute(String name); session.removeAttribute(String name);
此外,可以通过session对象的 getId()
方法获取到该session的JSESSIONID值。
3.3 Session对象的生命周期
- 创建:第一次执行request.getSession()时创建。
- 销毁:
- 1.服务器(非正常)关闭时。
- 2.session过期/失效(默认30分钟,这个默认时间可以在web.xml中修改)。
<session-config> <session-timeout>30</session-timeout> </session-config>
需要注意的是失效时间的起算点,即从何时开始计算30分钟?从不操作服务器端的资源开始计时(即从最近一次读取session数据开始)。 - 3.手动销毁session:
session.invalidate();
。
也就是说,客户端在一次会话中任何资源都共用一个session对象。
问题:浏览器关闭,session就销毁了吗?
不对,session存储在服务端,和客户端没多大关系,只要客户端没有操作session,等一段时间后,session自动销毁。
但是,关闭浏览器后,cookie中的JSESSIONID就丢失了,也就无法再找到对应的session数据。可以在发送session给客户端前将jsessionid当成cookie的属性并配置cookie的持久化时间持久化到客户端磁盘,这样再次打开浏览器时jsessionid就不会丢失。代码大致如下:
HttpSession session = request.getSession(); session.setAttribute("username","Tom"); String id = session.getId(); //获取JSESSIONID值 Cookie cookie = new Cookie("JSESSIONID",id); //"JSESSIONID"为固定值 cookie.setPath("/CookieDemo"); cookie.setMaxAge(12*60*60); //JSESSIONID持久化保存12小时 response.addCookie(cookie); response.getWriter().write("JSESSIONID:"+id); System.out.println(session.getAttribute("username"));
本文永久更新链接地址 : http://www.linuxidc.com/Linux/2018-01/150465.htm
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Java Servlet & JSP Cookbook
Bruce W. Perry / O'Reilly Media / 2003-12-1 / USD 49.99
With literally hundreds of examples and thousands of lines of code, the Java Servlet and JSP Cookbook yields tips and techniques that any Java web developer who uses JavaServer Pages or servlets will ......一起来看看 《Java Servlet & JSP Cookbook》 这本书的介绍吧!