会话管理(一)---Cookie技术及其使用

来源:互联网 发布:电动牙刷 推荐 知乎 编辑:程序博客网 时间:2024/06/07 01:50

会话

  • 什么是会话?

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

  • 会话过程中要解决的一些问题?

每个用户在使用浏览器与服务器进行会话的过程中,不可避免各自会产生一些数据,程序要想办法为每个用户保存这些数据。
例如:用户点击超链接通过一个servlet购买了一个商品,程序应该想办法保存用户购买的商品,以便于用户点结帐servlet时,结帐servlet可以得到用户购买的商品为用户结帐。

  • 保存会话数据的两种技术
    Cookie
    Session

Cookie

什么是Cookie

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

Cookie的使用

Cookie是基于set-Cookie响应头和Cookie请求头工作的,服务器可以发送set-Cookie请求头命令浏览器保存一个cookie信息,浏览器会在访问服务器时以Cookie请求头的方式带回之前保存的信息。

  • request.getCookies();
  • response.addCookie(Cookie c);
  • new Cookie(String name,String value)//Cookie在构造的时候就需要设定好cookie的名字和值
  • getName();
  • getValue();
  • setValue();
  • 没有setName()方法
  • setMaxAge与getMaxAge方法
    一个Cookie如果没有设置过MaxAge则这个Cookie是一个会话级别的Cookie,这个Cookie信息打给浏览器后浏览器会将它保存在浏览器的内存中,这意味着只要浏览器已关闭随着浏览器内存的销毁Cookie信息也就消失了.一个Cookie也可以设置MaxAge,浏览一一旦发现收到的Cookie被设置了MaxAge,则会将这个Cookie信息以文件的形式保存在浏览器的临时文件夹中,保存到指定的时间到来位置.这样一来即使多次开关浏览器,由于这些浏览器都能在临时文件夹中看到cookie文件,所以在cookie失效之前cookie信息都存在.
    想要命令浏览器删除一个Cookie,发送一个同名同path的cookie,maxage设置为0,浏览器以名字+path识别cookie,发现同名同path,cookie覆盖后立即超时被删除,从而就删除了cookie.

  • setPath与getPath方法

用来通知浏览器在访问服务器中的哪个路径及其子路径时带着当前cookie信息过来
如果不明确设置,则默认的路径是发送Cookie的Servlet所在的路径

http://localhost/Day05/servlet/...
  • setDomain与getDomain方法
    用来通知浏览器在访问哪个域名的时候带着当前的cookie信息.但是要注意,现代的浏览器一旦发现cookie设置过domain信息则会拒绝接受这个Cookie.我们平常不要设置这个方法。

Cookie实例

模拟购物网站中显示曾经看过的书的功能。
首先,新建一个Book类,用JavaBean的形式设置与书有关的一些信息,代码如下:

package me.zipstream.domain;public class Book {    private String id;    private String name;    private String price;    private String author;    private String publish;    private String description;    public Book(){}    public Book(String id, String name, String price, String author,            String publish, String description) {        super();        this.id = id;        this.name = name;        this.price = price;        this.author = author;        this.publish = publish;        this.description = description;    }    public String getId() {        return id;    }    public void setId(String id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getPrice() {        return price;    }    public void setPrice(String price) {        this.price = price;    }    public String getAuthor() {        return author;    }    public void setAuthor(String author) {        this.author = author;    }    public String getPublish() {        return publish;    }    public void setPublish(String publish) {        this.publish = publish;    }    public String getDescription() {        return description;    }    public void setDescription(String description) {        this.description = description;    }   }

再新建一个BookDao类,模拟存储书的信息的数据库,代码如下:

package me.zipstream.cookie;import java.util.LinkedHashMap;import java.util.Map;import me.zipstream.domain.Book;public class BookDao {    private BookDao(){}    private static Map<String, Book> bookMap = new LinkedHashMap<String, Book>();    static{        bookMap.put("1", new Book("1", "第一行代码", "79.0", "郭霖", "人民邮电出版社", "Android开发入门经典"));        bookMap.put("2", new Book("2", "暗时间", "35.0", "刘未鹏", "电子工业出版社", "学会正确的思考方式"));        bookMap.put("3", new Book("3", "把时间当朋友", "59.0", "李笑来", "电子工业出版社", "运用心智获得解放"));        bookMap.put("4", new Book("4", "异类", "36.0", "Malcolm GladWell", "中信出版社", "不一样的成功启示录"));    }    public static Map<String, Book> getBooks(){        return bookMap;    }    public static Book getBook(String id){        return bookMap.get(id);    }}

新建BookListServlet,用于显示书的列表,代码如下:

package me.zipstream.cookie;import java.io.IOException;import java.util.Map;import javax.servlet.ServletException;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import me.zipstream.domain.Book;public class BookListServlet extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        response.setContentType("text/html;charset=utf-8");        //查询数据库中所有的书并展示        Map<String, Book> map = BookDao.getBooks();        for (Map.Entry<String, Book> entry : map.entrySet()){            Book book = entry.getValue();            response.getWriter().write("<a href='"+ request.getContextPath()                     +"/servlet/BookInfoServlet?id="+ book.getId() +"'>"+ book.getName()                     +"</a><br>");        }        response.getWriter().write("<hr>");        //显示之前看过的书        Cookie[] cs = request.getCookies();        Cookie findC = null;        if (cs != null){            for (Cookie c : cs){                if ("last".equals(c.getName())){                    findC = c;                }            }        }        if (findC == null){            response.getWriter().write("您没有看过任何书!");        } else{            response.getWriter().write("您曾经看过的书:" + "<br>");            String[] ids = findC.getValue().split(",");            for (String id : ids){                Book book = BookDao.getBook(id);                response.getWriter().write(book.getName() + "<br>");            }        }    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        doGet(request, response);    }}

最后新建BookInfoServlet,显示每本书的相信信息并实现曾经看过的书的算法,代码如下:

package me.zipstream.cookie;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;import me.zipstream.domain.Book;public class BookInfoServlet extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        response.setContentType("text/html;charset=utf-8");        //1,获取要看的书的id,查询数据库,输出这本书的详细信息        String id = request.getParameter("id");        Book book = BookDao.getBook(id);        if (book == null){            response.getWriter().write("找不到这本书");        } else{            response.getWriter().write("<h1>书名:"+ book.getName() +"</h1>");            response.getWriter().write("<h3>作者:"+ book.getAuthor() +"</h3>");            response.getWriter().write("<h3>售价:"+ book.getPrice() +"</h3>");            response.getWriter().write("<h3>出版社:"+ book.getPublish() +"</h3>");            response.getWriter().write("<h3>描述信息:"+ book.getDescription() +"</h3>");        }        //2,发送Cookie保存最近看过的书        // 没看过书   ---> 看了1,发送Cookie带着1        // 看过1     ---> 看了2,发送Cookie带着2,1        // 看过2,1   ---> 看了3,发送Cookie带着3,2,1        // 看过3,2,1 ---> 看了4,发送Cookie带着4,3,2        // 看过4,3,2 ---> 看了3,发送Cookie带着3,4,2        String ids = "";        Cookie[] cs = request.getCookies();        Cookie findC = null;        if (cs != null){            for (Cookie c : cs){                if ("last".equals(c.getName())){                    findC = c;                }            }        }        if (findC == null){            //说明之前没有看过书的记录            ids += book.getId();        } else{            //说明之前有看过的书的历史记录,需要根据历史记录算一个新的记录出来            String[] olds = findC.getValue().split(",");            StringBuffer buffer = new StringBuffer();            //将本次看的书的id添加到buffer中            buffer.append(book.getId()+",");            //遍历Cookie中的历史记录,如果id与本次不同而且添加后长度不超过3则添加            for (int i=0; i<olds.length && buffer.toString().split(",").length<3; i++){                String old = olds[i];                if (!old.equals(book.getId())){                    buffer.append(old + ",");                }            }            ids = buffer.substring(0, buffer.length()-1);        }        Cookie lastC = new Cookie("last", ids);        lastC.setMaxAge(3600*24*30);        lastC.setPath(request.getContextPath());        response.addCookie(lastC);    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        doGet(request, response);    }}
0 0
原创粉丝点击