1.简单理解Cookie

Cookie就是网站在本地终端上的存缓数据。有些网站会保存你的一些信息,如用户名、密码、上次登录时间……这种技术出现的需求主要是http协议的特点—-无状态性 ,每次用户请求得到响应后,服务器断开与客户端的连接。这样,所有的链接都会一视同仁。那我们想区分不同用户不同的链接怎么办呐?用户带着自己的简历(cookie)去呗!cookie保存一些用户的基本信息。这种技术也有很大的缺点,什么窃取、篡改、攻击啦,讲起来没完,有兴趣可以自己去查阅相关文章。以后,可能我也会写,再说吧。

2.Cookie的小细节

一个web浏览器只能存放300个cookie。
一个web站点只能向一个web浏览器传送20个cookie。
一个cookie只能带到“自己来的地方”,即不可跨域性
一个cookie的大小限制在4KB以内。
cookie默认是会话级别的,即浏览器关闭cookie清除。
使用setMaxAge来设置cookie的保存时间,单位是秒

3.Cookie的属性

name —cookie的名字。
value —值。
maxAge —存放时间,单位毫秒。
domain —域,可以获取该cookie的域名。
path —使用路径。访问哪个站点会带着。
secure —安全性。是不是仅采用安全传输协议。
version —cookie的版本号。(了解)0表示遵循Netscape的Cookie规范,1表示遵循W3C的RFC 2109规范

4.Cookie的方法

1.Cookie(String name , String value)
2.setValue与getValue
3.setMaxAge与getMaxAge //设置cookie的保存时间
4.setPath与getPath
//cookie的有效路径。例如:设为/Day07,访问/Day07下面的所有web资源均会带上这个cookie;默认情况是创建cookie的servlet的目录,比如是/Day06/servlet/ServletDemo1创建了这个cookie,那么/Day06/servlet就是他的有效路径
5.setDomain与getDomain
//设置cookie会在访问那些网站时会带过去。当设为别人的网站时,这种cookie称为第三方cookie,IE会拒绝这种cookie。
6.getName

5.Cookie的使用

1.发送

1.使用Cookie的构造方法创建一个Cookie: Cookie c = new Cookie( str_name , str_value );
2.设置这个Cookie的保存时间:
c.setMaxAge(24*60*60);//一天
3.使用response回送给客户机:response.addCookie(c);
2.解析
1.使用request获取Cookie数组:Cookie cookies[] =request.getCookies();
2.对数组进行遍历,找到我们要找的cookie:

for (Cookie coo: cookies){
        if(coo.getName().equals("BookHistory")){
                //找到这个cookie,拿到cookie中保存的数据
                coo.getValue();

                break;
        }
}

6.cookie的保存和删除

setMaxAge()方法:
1)正值时,以毫秒为单位的有效时间。当设置以前的时间,就会其无效(成老古董了,就认为无效了)。
2)负值时,cookie不会永久保存,会在浏览器退出时,进行删除。当不设置时,有效期就是会话进程,默认是负值了。
3)零值时,会导致cookie删除。

Cookie的简单案例:显示用户最近浏览的三样商品

案例的注意事项:
1)不能使用太多的cookie来保存数据,最好只使用一个。
2)简单起见,使用DB类来代替数据库。
3)显示最近浏览的三本书时,最多有三本,多了不要。
4)最近浏览的,放在最上面。

/**
 * 模拟数据库
 * @author majin
 */
class DB {
    private static LinkedHashMap<String, Book> books = new LinkedHashMap<String, Book>();

    static {
        books.put("1", new Book("1", "海贼王", "尾田荣一郎", "一本绝世佳书"));
        books.put("2", new Book("2", "死神", "久保带人", "一本好漫画"));
        books.put("3", new Book("3", "火影忍者", "岸本齐史", "一本好漫画"));
        books.put("4", new Book("4", "嗜血狂袭", "不知道", "一本黄色漫画"));
    }

    //拿到所有的书的集合
    public static LinkedHashMap<String, Book> getAll() {
        return books;
    }
}

封装书的属性的类

class Book {
    private String id = null;
    private String name = null;
    private String author = null;
    private String description = null;
    //constructor
    //getter and setter
}
/**
 * 商城界面:显示商品信息 、 显示用户最近浏览的几件商品
 * 当点击商品名称时,会跳转到BookServelt来显示商品的详细信息
 * @author majin
 */
public class Supermarket extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 设置编码
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.print("当前网站上的商品有:<br/>");

        // 显示网站上的商品
        Map<String, Book> allBook = DB.getAll();
        for (Map.Entry<String, Book> entry : allBook.entrySet()) {//迭代map集合
            Book bookEntry = entry.getValue();// 得到书
            out.print("<a href='/Day07/servlet/BookServlet?id="+bookEntry.getId()+"' target='_blank'>"+bookEntry.getName()+"</a><br/>");
        }

        //显示用户浏览过的书
        out.print("<br/>你浏览的书有:<br/>");
        Cookie cookies[] = request.getCookies();
        for (Cookie coo: cookies){
            if(coo.getName().equals("BookHistory")){//找到这个cookie
                String  ids= coo.getValue();// id  = 1,3,2
                String[] idarr=ids.split(",");
                for(String idEntry : idarr){
                    String name = allBook.get(idEntry).getName();
                    out.print("书名:《"+name+"》<br/>");
                }
                break;//找到我们想要的cookie了,不需要再遍历了
            }
        }
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}
/**
 * 用于显示书的详细信息 和 客户端 回写cookie
 * cookie用来记录用户最近浏览的 三本书
 * @author majin
 */
public class BookServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        // 要显示的书的id
        String idEntry = request.getParameter("id");

        // 显示书的详细信息
        out.print("当前书的详细信息:<br/>");
        Map<String, Book> allBook = DB.getAll();

        String name = allBook.get(idEntry).getName();
        String author = allBook.get(idEntry).getAuthor();
        String description = allBook.get(idEntry).getDescription();

        out.print("书名:《" + name + "》<br/>");
        out.print("作者:" + author + "<br/>");
        out.print("描述:" + description + "<br/>");

        // 写回cookie,保存客户最近浏览过的三本书
        String oldID = null;
        Cookie cookies[] = request.getCookies();
        for (Cookie coo : cookies) {
            if (coo.getName().equals("BookHistory")) {// 找到这个cookie
                oldID = coo.getValue();// id = 1,3,2
                break;
            }
        }
        String newid = createNewID(oldID, idEntry);

        Cookie newCoo = new Cookie("BookHistory", newid);
        newCoo.setMaxAge(1*24*60*60);//单位秒
        newCoo.setPath("/Day07/servlet");
        response.addCookie(newCoo);
    }

    /**
     * 创建新的cookie所保存的id
     * 
     * @param oldID
     *            cookie以前所保存的ID
     * @param idEntry
     *            用户当前浏览的书ID
     * @return 新的cookie的ID
     */
    private String createNewID(String oldID, String idEntry) {
        /*
         * oldID  idEntry   newID 
         * null     1       1       情况一
         * 1,2,3    2       2,1,3   情况二
         * 1,2,3    4       4,1,2   情况三
         * 1,2      3       3,1,2   情况四
         */
        if (oldID == null) {//第一种情况
            return idEntry;
        }
        //使用了 强转 后,发现不对
        //未见过的科技,使用了LinkedList的构造方法。
        LinkedList<String> list = new LinkedList<String>(Arrays.asList(oldID.split(",")));// 使用,分割
        /*
        if (list.contains(idEntry)) { // 第二种情况
            list.remove(idEntry);
            list.addFirst(idEntry);
        } else {
            if (list.size() == 3) { //第三种情况
                list.removeLast();
                list.addFirst(idEntry);
            } else { //第四种情况
                list.addFirst(idEntry);
            }
        }
        */
        //对上面的代码进行优化
        if (list.contains(idEntry)) { 
            list.remove(idEntry);
        } else {
            if (list.size() == 3) {
                list.removeLast();
            }
        }
        list.addFirst(idEntry);

        StringBuffer sb = new StringBuffer();
        for (String s : list) {
            sb.append(s + ",");
        }
        sb.deleteCharAt(sb.length()-1);
        return sb.toString();
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

持续更新,未完待续……