zoukankan      html  css  js  c++  java
  • 会话管理--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>
  • 相关阅读:
    zoj 2001 Adding Reversed Numbers
    hdu 2391 Filthy Rich (简单dp)
    hdu 1128 (hash)
    华为交换机有关BGP的相关配置
    Cent os 6.8添加中文字体
    Liunx之始
    自己鼓励自己
    UML用例图中包含(include)、扩展(extend)和泛化(generalization)三种关系详解(转载)
    20091125心情感觉还不错
    DataTable 行列转换
  • 原文地址:https://www.cnblogs.com/nicker/p/6558540.html
Copyright © 2011-2022 走看看