什么是会话:用户打开浏览器,点击多个超链接,访问服务器的多个web资源,然后关闭浏览器,整个过程就称为一个会话;
会话过程需要解决的问题:每个用户在使用浏览器与服务器进行会话的过程中,都可能会产生一些数据,这些输入如何来进行保存?比如用户在购物网站浏览的商品记录,用户添加购物车的记录等等这些信息如何进行存储?在程序中会话跟踪是一件非常重要的事情,一个用户的所有请求操作都应该属于同一个会话,而另一个人的所有请求操作应该属于另一个人,二者不能混淆!当想到需要在保存数据时,我们首先肯定会想到使用域对象,这些数据是否可以使用Request或者ServletContext对象来保存呢?
首先我们举例说明:登录的场景
1 Context对象:
小张: 输入“张三” (保存数据: context.setAttribute("name","张三")) -> 用户主页(显示“张三”)
小李: 输入“李四”(保存数据:context.setAttribute("name","李四")) -> 用户主页(显示“李四”)
context是所有用户公有的资源,因此当小李登录后,用户主页将全部显示为“李四”,新的数据将会覆盖原有的数据,因此不能够使用context对象;
2 Request对象:该对象只在同一个页面有效,当需要进行页面跳转的时候,显然必须使用转发技术来实现,因此Request对象也不能够有效解决该问题。
会话技术
为了解决上述的问题,这里引入了会话技术,其中会话技术主要分为两个部分,cookie技术和session技术,前者将数据保存在客户端,后者将数据保存在服务器。
- Cookie技术:Cookie是客户端技术,服务器把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。
- Session技术:Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务。
(一) Cookie技术
1.1 Cookie技术核心
Cookie类:用于存储会话数据
1)构造Cookie对象
- Cookie(java.lang.String name, java.lang.String value)
2)设置cookie
- void setPath(java.lang.String uri) :设置cookie的有效访问路径
- void setMaxAge(int expiry) : 设置cookie的有效时间
- void setValue(java.lang.String newValue) :设置cookie的值
3)发送cookie到浏览器端保存
- void response.addCookie(Cookie cookie) : 发送cookie
4)服务器接收cookie:
- Cookie[] request.getCookies() : 接收cookie,返回所有cookie的数据信息
1.2 Cookie原理
1)服务器创建cookie对象,把会话数据存储到cookie对象中。
- new Cookie("name","value");
2)服务器发送cookie信息到浏览器
- response.addCookie(cookie);
举例: set-cookie: name=Infaraway ( 隐藏发送了一个set-cookie名称的响应头 )
3)浏览器得到服务器发送的cookie,然后保存在浏览器端。
4)浏览器在下次访问服务器时,会带着cookie信息
举例: cookie: name=Infaraway (隐藏带着一个叫cookie名称的请求头)
5)服务器接收到浏览器带来的cookie信息
- request.getCookies();
1 package com.infaraway.servlet; 2 3 import javax.servlet.ServletException; 4 import javax.servlet.http.Cookie; 5 import javax.servlet.http.HttpServletRequest; 6 import javax.servlet.http.HttpServletResponse; 7 import java.io.IOException; 8 9 /** 10 * Created by :Infaraway 11 * DATE : 2017/3/25 12 * Time : 22:08 13 * Funtion : cookie测试 14 */ 15 public class CreateCookie { 16 public void doGet(HttpServletRequest request, HttpServletResponse response) 17 throws ServletException, IOException { 18 //1.创建Cookie对象 19 Cookie cookie1 = new Cookie("name","Infaraway"); 20 //Cookie cookie2 = new Cookie("email","Infaraway@qq.com"); 21 //Cookie cookie1 = new Cookie("email","Infaraway@qq.com"); 22 23 /** 24 * 1)设置cookie的有效路径。默认情况:有效路径在当前web应用下。 /cookie 25 */ 26 //cookie1.setPath("/cookie"); 27 //cookie2.setPath("/basisJavaWeb"); 28 /** 29 * 2)设置cookie的有效时间 30 * 正整数:表示cookie数据保存浏览器的缓存目录(硬盘中),数值表示保存的时间。 31 * 负整数:表示cookie数据保存浏览器的内存中。浏览器关闭cookie就丢失了! 32 * 零:表示删除同名的cookie数据 33 */ 34 //cookie1.setMaxAge(20); //20秒,从最后不调用cookie开始计算 35 cookie1.setMaxAge(-1); //cookie保存在浏览器内存(会话cookie) 36 //cookie1.setMaxAge(0); 37 38 //2.把cookie数据发送到浏览器(通过响应头发送: set-cookie名称) 39 //response.setHeader("set-cookie", cookie.getName()+"="+cookie.getValue()+",email=eric@qq.com"); 40 //推荐使用这种方法,避免手动发送cookie信息 41 response.addCookie(cookie1); 42 //response.addCookie(cookie2); 43 //response.addCookie(cookie1); 44 45 //3.接收浏览器发送的cookie信息 46 /*String name = request.getHeader("cookie"); 47 System.out.println(name);*/ 48 Cookie[] cookies = request.getCookies(); 49 //注意:判断null,否则空指针 50 if(cookies!=null){ 51 //遍历 52 for(Cookie c:cookies){ 53 String name = c.getName(); 54 String value = c.getValue(); 55 System.out.println(name+"="+value); 56 } 57 }else{ 58 System.out.println("没有接收cookie数据"); 59 } 60 } 61 }
1.3 Cookie的细节
1)void setPath(java.lang.String uri) :设置cookie的有效访问路径。有效路径指的是cookie的有效路径保存在哪里,那么浏览器在有效路径下访问服务器时就会带着cookie信息,否则不带cookie信息。
2)void setMaxAge(int expiry) : 设置cookie的有效时间。
- 正整数:表示cookie数据保存浏览器的缓存目录(硬盘中),数值表示保存的时间。
- 负整数:表示cookie数据保存浏览器的内存中。浏览器关闭cookie就丢失了!!
- 零:表示删除同名的cookie数据
3)Cookie数据类型只能保存非中文字符串类型的。可以保存多个cookie,但是浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。
1.4 案例-查看用户浏览器过的商品
首先是商品的实体类:
1 package com.infaraway.entity; 2 3 4 /** 5 * Created by :Infaraway 6 * DATE : 2017/3/25 7 * Time : 14:34 8 * Funtion : 商品类 9 */ 10 public class Product { 11 12 private String id; 13 private String proName; 14 private String proType; 15 private double price; 16 public String getId() { 17 return id; 18 } 19 public void setId(String id) { 20 this.id = id; 21 } 22 public String getProName() { 23 return proName; 24 } 25 public void setProName(String proName) { 26 this.proName = proName; 27 } 28 public String getProType() { 29 return proType; 30 } 31 public void setProType(String proType) { 32 this.proType = proType; 33 } 34 public double getPrice() { 35 return price; 36 } 37 public void setPrice(double price) { 38 this.price = price; 39 } 40 public Product(String id, String proName, String proType, double price) { 41 super(); 42 this.id = id; 43 this.proName = proName; 44 this.proType = proType; 45 this.price = price; 46 } 47 public Product() { 48 super(); 49 // TODO Auto-generated constructor stub 50 } 51 @Override 52 public String toString() { 53 return "Product [ 54 + proName + ", proType=" + proType + "]"; 55 } 56 57 }