Servlet的Cookie和HttpSession

1.会话概述

  什么是会话?

  如同打电话

  会话解决的问题?

  保持各个客户端自己的数据

2.Cookie

   1.Cookie的定义

  

  2.Cookie的主要方法

注意以下几点

  name: 名称不能唯一确定一个cookie。路径可能不同

  value: 不能存中文

  path: 默认是写入cookie那个应用的访问路径

  如:http://localhost:8080/day10/servlet/cookieDemo1

  Path: /day10/servlet/

  当客户端访问服务器其它资源时,根据访问路径来决定是否带着cookie到服务器

  当访问的路径是以cookiepath开头的路径,就带cookie,否则就不带。

  maxAge: cookie的保存时间。默认是-1(表示保存在浏览器的内存中)。单位是秒

    负数:cookie存在浏览器的内存中。

    0:删除。路径要保持一致,否则会删错了。

    正数:缓存(持久化到磁盘中)的时间。

Demo1Cookie设置最后访问时间 

 

 1         response.setContentType("text/html; charset = UTF-8");
 2         PrintWriter out = response.getWriter();
 3         //得到Cookie,输出上次的访问时间,第一次访问是没有的
 4         Cookie[] cookies = request.getCookies();
 5         for (int i = 0; cookies != null && i < cookies.length; i++) {
 6             if(cookies[i].getName().equals("lastAccessTime")){
 7                 out.write("你最后的访问时间为"+cookies[i].getValue());
 8             }
 9         }
10         //设置本次访问时间到Cookie
11         //设置清除cookie
12         out.print("<a href='"+request.getContextPath()+"/servlet/CookieDemo2'>clear</a>");
13         //得到当前时间,创建cookie
14         SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
15         String time = sdf.format(new Date());
16         Cookie lck = new Cookie("lastAccessTime", time);
17         //设置最大时间
18         lck.setMaxAge(60*5);
19         //设置可访问的路径
20         lck.setPath(request.getContextPath());
21         //添加cookie到浏览器
22         response.addCookie(lck);

 

清除Cookie的Servlet

清除Cookie其实就是设置Cookie的MaxAge为0,但是要注意:Path必须是和你要设置的Cookie相同,否则Cookie来自不同路径同名属于不同的Cookie

        Cookie ck = new Cookie("lastAccessTime", "");
        //设置cookie存活时间  秒
        ck.setMaxAge(0);
        //设置cookie的路径,决定哪些路径会带着这个cookie
        ck.setPath(request.getContextPath());
        //添加
        response.addCookie(ck);

 

Demo2历史记录的案例

原理:

如图,当你浏览一本书的时候,还设置了一次Cookie,如果以前没有历史记录,那么创建一个Cookie放历史记录,否则,修改原有Cookie,根据一定的规则,增加Cookie中id的排列规则(这里用'-'用作分隔符号让字符串去切割).所有商品中的历史信息会读取响应的Cookie,如果有,那么读取到,切割id,遍历,查询,输出书名字。

原理大概如此上代码:

  ShowAllBooks:

  

 1         response.setContentType("text/html; charset=UTF-8");
 2         PrintWriter out = response.getWriter();
 3         Map<String, Book> map = Utils.getAllBook();
 4         out.write("所有的书<br/>");
 5         //遍历map
 6         for (Map.Entry<String, Book> book : map.entrySet()) {
 7             out.write("<a href='"+request.getContextPath()+"/servlet/BookDetails?id="+book.getKey()+"',target='blank'>"+book.getValue().getName()+"</a><br>");
 8         }
 9         out.write("浏览历史<br/>");
10         //遍历cookie
11         Cookie[] cookies = request.getCookies();
12         for (int i = 0; cookies!=null && i < cookies.length; i++) {
13             if(cookies[i].getName().equals("history")) {
14                 String[] s = cookies[i].getValue().split("-");
15                 for (int j = s.length; j >= 0 ; j--) {
16                     out.write(Utils.getMapById(s[j]).getName()+"<br/>");
17                 }
18             }
19         }

ShowBooksDetail:

  

 1     public void doGet(HttpServletRequest request, HttpServletResponse response)
 2             throws ServletException, IOException {
 3         //逻辑:获取到发送过来的id,对它进行处理成一个字符串以-连接代表历史记录的顺序
 4         response.setContentType("text/html; charset=UTF-8");
 5         PrintWriter out = response.getWriter();
 6         String id = request.getParameter("id");
 7         out.write(Utils.getMapById(id).toString());
 8         Cookie history = new Cookie("history", getCookie(request, id));
 9         response.addCookie(history);
10     }
11     //根据id和request来获取
12     public String getCookie(HttpServletRequest request, String id) {
13         Cookie[] cookies = request.getCookies();
14         if(cookies == null) {
15             return id;
16         }
17         
18         String s = null;
19         // 装入字符串
20         for (int i = 0; i < cookies.length; i++) {
21             if(cookies[i].getName().equals("history")){
22                 s = cookies[i].getValue();
23             }
24         }
25         
26         if(s == null){
27             return id;
28         }
29         //分解
30         String[] arr = s.split("-");
31         //装入list
32         List<String> list = new ArrayList<String>(Arrays.asList(arr)); 
33         //如果包含id,那么移除
34         if(s.contains(id)){
35             list.remove(id);
36         } else {
37             if(list.size()<3) {
38                 
39             } else {
40                 list.remove(0);
41             }
42         }
43         list.add(id);
44         //最后装入StringBuffer再转换成数组
45         StringBuffer sb = new StringBuffer();
46         for (int i = 0; i < list.size(); i++) {
47             if(i>0) {    
48                 sb.append("-");
49             }     
50             sb.append(list.get(i));
51         }
52         
53         return sb.toString();
54     }

中间的字符串处理部分可能有点复杂,可以优化。但是也算完成了,没有给Cookie加入过时的时间,所以浏览器关闭就被清理了。

 

3.HttpSession

1、HttpSession的定义

  

  主要方法:

  void setAttribute(String name,Object value);      //设置Session的值

  Object getAttribute(String name);          //得到Session

  void removeAttribute(String name);         //删除指定的值

  HttpSession.getId():                 //得到Id

  setMaxInactiveInterval(int interval)           //设置session的存活时间 秒   

  invalidate() 使此会话无效   

         

2、为什么要学HttpSession?

> 它也是一个域对象: session   servletContext  request

> 同一个会话下,可以使一个应用的多个资源共享数据

> cookie客户端技术,只能存字符串。HttpSession服务器端的技术,它可以存对象

 

3、Session的内部执行原理

HttpSession request.getSession():内部执行原理

1、获取名称为JSESSIONID的cookie的值。

2、没有这样的cookie,创建一个新的HttpSession对象,分配一个唯一的SessionID,并且向客户端写了一个名字为JSESSIONID=sessionID的cookie

3、有这样的Cookie,获取cookie的值(即HttpSession对象的值),从服务器的内存中根据ID找那个HttpSession对象:

找到了:取出继续为你服务。

找不到:从2开始。

 

4、Session的状态

 

 5、Demo1简单的购物车

 

Servlet1:首页

 1     public void doGet(HttpServletRequest request, HttpServletResponse response)
 2             throws ServletException, IOException {
 3         response.setContentType("text/html; charset=UTF-8");
 4         PrintWriter out = response.getWriter();
 5 
 6         out.write("选择你要购买的<br/>");
 7         //遍历到所有的书
 8         Map<String, Book> allBook = Utils.getAllBook();
 9         for (Entry<String, Book> book : allBook.entrySet()) {
10             out.write("<a href='" + request.getContextPath()
11                     + "/servlet/addBook?id="+book.getKey()+"' target='_blank'>"
12                     + book.getValue().getName() + "<a/><br/>");
13         }
14         out.write("<a href='/day10_01_session/servlet/ShowCart' target='_blank'>查看cart</a>");
15     }

 

Servlet2:购物车页面

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html; charset=UTF-8");
        PrintWriter out = response.getWriter();
        Map<Book,Integer> books = (Map<Book, Integer>) request.getSession().getAttribute("books");
        //如果session为空说明没有买书
        if(books == null) {
            out.write("你还没有购买书籍");
            return;
        }
        //否则遍历这个集合,取出book对象遍历输出
        for (Entry<Book,Integer> book : books.entrySet()) {
            out.write(book.getKey().getName()+"num: "+book.getValue().toString());
        }
        
    }

 

Servlet3:买书页面(详情页面)

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String id = request.getParameter("id");
        Book book = Utils.getMapById(id);
        HttpSession session = request.getSession();
        //得到Session ,创建一个map集合,保存这个session,
        Map<Book, Integer> books = (Map<Book, Integer>) request.getSession().getAttribute("books");
        //第一次为空所以如果是第一次那么就为null,表示这个书只有一本,那么新创建一个集合,放入这本书
        if(books == null) {
            books = new HashMap<Book, Integer>();
            books.put(book, 1);
        }else {
            //如果不是第一次且已经包含这本书了,那么就使这本书的value+1
            if(books.containsKey(book)){
                books.put(book, books.get(book)+1);
            }else {
                //否则,放入这1个这本书就行
                books.put(book, 1);
            }
        }
        //将books这个map集合放入session
        session.setAttribute("books", books);
    }

没有设置Session的过期时间,可以自己设置,在上面的有两种设置方法. 

 

6、用户禁用了Cookie的解决办法

解决方案:

方案一:在主页上给出提示:请不要禁用您的cookie

方案二:URL重写。必须对网站的所有地址都重写。

http://url--->http://url;JSESSIONID=111

response.encodeURL(String url);

看浏览器有没有发送cookie请求消息头,没有就重写URL,有就不重写。

request.getSession();必须写

posted @ 2017-09-05 12:59  Soe  阅读(435)  评论(0编辑  收藏  举报