Dev_Nick

导航

会话管理--cookie && session

会话:可以简单的理解为用户开一个浏览器,点击多个超链接,访问服务器的多个web资源,然后关闭浏览器,整个过程称之为一个会话。

会话管理:对一个会话过程中浏览器和服务器之间产生的会话数据进行管理。

常用的会员管理技术有两种:cookie 和 session。

Cookie

cookie是客户端技术,服务器把每个用户的数据以cookie的形式写给用户给的浏览器中。当用户使用浏览量再去访问服务器中的web资源时,就会带着各自的数据去,这样web资源处理的就是用户各自的数据了。

javax.servlet.http.Cookie类用于创建一个Cookie,response接口中也定义了一个addCookie的方法,它用于在其响应头中增加一个相应的Set-Cookie头字段。同样,request  接口中也定义了一个getCookies方法,它用于获取客户端提交的Cookie。

Cookie中常用的API

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的值

注意:

(1)cookie有效期参数的类型决定者浏览器接受到该cookie中时,cookie存储的地方:

    正整数:表示cookie数据保存浏览器的缓存目录(硬盘中),数值表示保存的时间。

    负整数:表示cookie数据保存浏览器的内存中。浏览器关闭cookie就丢失了!!

    零:表示删除同名的cookie数据。

(2)浏览器在cookie的有效路径下访问服务器时,请求头中才会携带该cookie,否则不带cookie信息。

3、发送cookie到浏览器端保存

void response.addCookie(Cookie cookie)  //发送cookie

4、服务器接收cookie

Cookie[] cookies = request.getCookies(); //获取cookie
//注意:判断null,否则空指针
if(cookies!=null){
    //遍历
    for(Cookie c:cookies){
        String name = c.getName();
        String value = c.getValue();
        System.out.println(name+"="+value);
    }
}else{
    System.out.println("没有接收cookie数据");
}

cookie注意的细节:

1、一个cookie只能标识一种信息,它至少含有一个标识该信息的名称(name)和设置值(value),并且value的值类型只能是string类型,不支持中文。

2、一个web站点可以给一个web浏览器发送多个cookie,一个web浏览器页可以存储多个web站点提供的cookie。

3、浏览量一般只允许存放300个cookie,每个站点最多存放20个cookie,每个cookie的大小限制为4KB。

4、如果创建了一个cookie,并将它发送到浏览器,默认情况下是一个会话级别的cookie(即存储在浏览器的内存中)。

cookie使用案例

查看用户浏览过的商品:通过访问详情在列表页显示用于最近3次访问的商品。

1、程序模块按照模块来分为三个包:

  ervlet包:网络服务操作类。

  dao包:数据访问操作类。

  entity包:实体类。

2、源码:

(1)实体类

 1 public class Product {
 2 
 3     private String id;
 4     private String proName;
 5     private String proType;
 6     private double price;
 7     public String getId() {
 8         return id;
 9     }
10     public void setId(String id) {
11         this.id = id;
12     }
13     public String getProName() {
14         return proName;
15     }
16     public void setProName(String proName) {
17         this.proName = proName;
18     }
19     public String getProType() {
20         return proType;
21     }
22     public void setProType(String proType) {
23         this.proType = proType;
24     }
25     public double getPrice() {
26         return price;
27     }
28     public void setPrice(double price) {
29         this.price = price;
30     }
31     public Product(String id, String proName, String proType, double price) {
32         super();
33         this.id = id;
34         this.proName = proName;
35         this.proType = proType;
36         this.price = price;
37     }
38     public Product() {
39         super();
40         // TODO Auto-generated constructor stub
41     }
42     @Override
43     public String toString() {
44         return "Product [id=" + id + ", price=" + price + ", proName="
45                 + proName + ", proType=" + proType + "]";
46     }
47     
48 }
View Code

(2)servlet类

  1)商品列表类

 1 public class ListServlet extends HttpServlet {
 2 
 3     public void doGet(HttpServletRequest request, HttpServletResponse response)
 4             throws ServletException, IOException {
 5         response.setContentType("text/html;charset=utf-8");
 6         //1.读取数据库,查询商品列表
 7         ProductDao dao = new ProductDao();
 8         List<Product> list = dao.findAll();
 9         
10         
11         //2.把商品显示到浏览器
12         PrintWriter writer = response.getWriter();
13         String html = "";
14         
15         html += "<html>";
16         html += "<head>";
17         html += "<title>显示商品列表</title>";
18         html += "</head>";
19         html += "<body>";
20         html += "<table border='1' align='center' width='600px'>";
21         html += "<tr>";
22         html += "<th>编号</th><th>商品名称</th><th>商品型号</th><th>商品价格</th>";
23         html += "</tr>";
24         //遍历商品
25         if(list!=null){
26             for(Product p:list){
27                 html += "<tr>";
28                 // /day11_hist/DetailServlet?id=1 访问DetailSErvlet的servlet程序,同时传递 名为id,值为1 的参数
29                 html += "<td>"+p.getId()+"</td><td><a href='"+request.getContextPath()+"/DetailServlet?id="+p.getId()+"'>"+p.getProName()+"</a></td><td>"+p.getProType()+"</td><td>"+p.getPrice()+"</td>";
30                 html += "<tr>";
31             }
32         }
33         html += "</table>";
34         
35         /**
36          * 显示浏览过的商品
37          */
38         html += "最近浏览过的商品:<br/>";
39         //取出prodHist的cookie
40         Cookie[] cookies = request.getCookies();
41         if(cookies!=null){
42             for (Cookie cookie : cookies) {
43                 if(cookie.getName().equals("prodHist")){
44                     String prodHist = cookie.getValue(); // 3,2,1
45                     String[] ids = prodHist.split(",");
46                     //遍历浏览过的商品id
47                     for (String id : ids) {
48                         //查询数据库,查询对应的商品
49                         Product p = dao.findById(id);
50                         //显示到浏览器
51                         html += ""+p.getId()+"&nbsp;"+p.getProName()+"&nbsp;"+p.getPrice()+"<br/>";
52                     }
53                 }
54             }
55         }
56 
57         
58         html += "</body>";
59         html += "</html>";
60         
61         writer.write(html);
62     }
63 
64     public void doPost(HttpServletRequest request, HttpServletResponse response)
65             throws ServletException, IOException {
66         doGet(request, response);
67     }
68 
69 }
View Code

  2)商品详情类

  1 public class DetailServlet extends HttpServlet {
  2 
  3     public void doGet(HttpServletRequest request, HttpServletResponse response)
  4             throws ServletException, IOException {
  5         response.setContentType("text/html;charset=utf-8");
  6         //1.获取编号
  7         String id = request.getParameter("id");
  8         
  9         //2.到数据库中查询对应编号的商品
 10         ProductDao dao = new ProductDao();
 11         Product product = dao.findById(id);
 12         
 13         //3.显示到浏览器
 14         PrintWriter writer = response.getWriter();
 15         String html = "";
 16         
 17         html += "<html>";
 18         html += "<head>";
 19         html += "<title>显示商品详细</title>";
 20         html += "</head>";
 21         html += "<body>";
 22         html += "<table border='1' align='center' width='300px'>";
 23         if(product!=null){
 24             html += "<tr><th>编号:</th><td>"+product.getId()+"</td></tr>";
 25             html += "<tr><th>商品名称:</th><td>"+product.getProName()+"</td></tr>";
 26             html += "<tr><th>商品型号:</th><td>"+product.getProType()+"</td></tr>";
 27             html += "<tr><th>商品价格:</th><td>"+product.getPrice()+"</td></tr>";
 28         }
 29         
 30         html += "</table>";
 31         html += "<center><a href='"+request.getContextPath()+"/ListServlet'>[返回列表]</a></center>";
 32         html += "</body>";
 33         html += "</html>";
 34         
 35         writer.write(html);
 36         
 37         
 38         /**
 39          * 创建cookie,并发送
 40          */
 41         //1.创建cookie
 42         Cookie cookie = new Cookie("prodHist",createValue(request,id));
 43         cookie.setMaxAge(1*30*24*60*60);//一个月
 44         //2.发送cookie
 45         response.addCookie(cookie);
 46     }
 47 
 48     /**
 49      * 生成cookie的值
 50      * 分析:
 51      *             当前cookie值                     传入商品id               最终cookie值
 52      *      null或没有prodHist          1                     1    (算法: 直接返回传入的id )
 53      *             1                  2                     2,1 (没有重复且小于3个。算法:直接把传入的id放最前面 )
 54      *             2,1                1                     1,2(有重复且小于3个。算法:去除重复id,把传入的id放最前面 )
 55      *             3,2,1              2                     2,3,1(有重复且3个。算法:去除重复id,把传入的id放最前面)
 56      *             3,2,1              4                     4,3,2(没有重复且3个。算法:去最后的id,把传入的id放最前面)
 57      * @return
 58      */
 59     private String createValue(HttpServletRequest request,String id) {
 60         
 61         Cookie[] cookies = request.getCookies();
 62         String prodHist = null;
 63         if(cookies!=null){
 64             for (Cookie cookie : cookies) {
 65                 if(cookie.getName().equals("prodHist")){
 66                     prodHist = cookie.getValue();
 67                     break;
 68                 }
 69             }
 70         }
 71         
 72         // null或没有prodHist
 73         if(cookies==null || prodHist==null){
 74             //直接返回传入的id
 75             return id;
 76         }
 77         
 78         // 3,21          2
 79         //String -> String[] ->  Collection :为了方便判断重复id
 80         String[] ids = prodHist.split(",");
 81         Collection colls = Arrays.asList(ids); //<3,21>
 82         // LinkedList 方便地操作(增删改元素)集合
 83         // Collection -> LinkedList
 84         LinkedList list = new LinkedList(colls);
 85         
 86         
 87         //不超过3个
 88         if(list.size()<3){
 89             //id重复
 90             if(list.contains(id)){
 91                 //去除重复id,把传入的id放最前面
 92                 list.remove(id);
 93                 list.addFirst(id);
 94             }else{
 95                 //直接把传入的id放最前面
 96                 list.addFirst(id);
 97             }
 98         }else{
 99             //等于3个
100             //id重复
101             if(list.contains(id)){
102                 //去除重复id,把传入的id放最前面
103                 list.remove(id);
104                 list.addFirst(id);
105             }else{
106                 //去最后的id,把传入的id放最前面
107                 list.removeLast();
108                 list.addFirst(id);
109             }
110         }
111         
112         // LinedList -> String 
113         StringBuffer sb = new StringBuffer();
114         for (Object object : list) {
115             sb.append(object+",");
116         }
117         //去掉最后的逗号
118         String result = sb.toString();
119         result = result.substring(0, result.length()-1);
120         return result;
121     }
122 
123     public void doPost(HttpServletRequest request, HttpServletResponse response)
124             throws ServletException, IOException {
125         doGet(request, response);
126     }
127 
128 }
View Code

(3)数据访问对象类

 1 public class ProductDao {
 2     //模拟"数据库",存放所有商品数据
 3     private static List<Product> data = new ArrayList<Product>();
 4     
 5     /**
 6      * 初始化商品数据
 7      */
 8     static{
 9         //只执行一次
10         for(int i=1;i<=10;i++){
11             data.add(new Product(""+i,"笔记本"+i,"LN00"+i,34.0+i));
12         }
13     }
14     
15     
16     
17     /**
18      * 提供查询所有商品的方法
19      */
20     public List<Product> findAll(){
21         return data;
22     }
23     
24     /**
25      * 提供根据编号查询商品的方法
26      */
27     public Product findById(String id){
28         for(Product p:data){
29             if(p.getId().equals(id)){
30                 return p;
31             }
32         }
33         return null;
34     }
35 
36 }
View Code

Session

session是服务器端的技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其共享的session对象,由于session为用户浏览器独享,所以用户在访问服务器web资源时,可以把各自的手放在各自的session中,当用户在去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务。

session原理

当浏览器第一次访问web站点的时候创建session对象时,会给session对象分配一个唯一的ID,名字为JSESSIONID。然后把JSESSIONID作为cookie的值发送给浏览量器保存。浏览器第二次访问web站点的时候,会带着JSESSIONID的cookie访问服务器。服务器得到JSESSIONID后,在服务器的内存中搜索是否存放了对应的session对象,如果有则直接返回该对象,如果没有会根据创建session时方法的参数进行创建或者返回null。

session常用API

1、创建

request.getSession(true) / request.getSession()  //创建或得到session对象。没有匹配的session编号,自动创建创对象。
request.getSession(false) //得到session对象。没有匹配的session编号,返回null

2、保存会话数据到session对象

void setAttribute(java.lang.String name, java.lang.Object value)  //保存数据
java.lang.Object getAttribute(java.lang.String name)  // 获取数据
void removeAttribute(java.lang.String name) // 清除数据

3、设置session对象

void setMaxInactiveInterval(int interval)  //设置session的有效时间
void invalidate()     //销毁session对象
java.lang.String getId()  //得到session编号

注意:默认情况下30分钟服务器会自动回收session对象。

除了用上述API来修改session有效时间外,还可以在web.xml中配置全局变量来设置session的有效时间,配置代码如下

<!-- 修改session全局有效时间:分钟 -->
<session-config>
    <session-timeout>1</session-timeout>
</session-config>

 

posted on 2017-03-16 11:24  Dev_Nick  阅读(243)  评论(0编辑  收藏  举报