Cookie入门

1、什么是会话?

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

 

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

程序要想办法为每个用户保存浏览器和服务器会话过程中产生的数据。

 

3、用户购买的商品保存在requestservletContext中行不行?

request域不行,一次请求一次响应结束后,域就没了。

servletContext域不行,多个浏览器并发访问服务器,第一个浏览器在域里设置的属性值,第二个浏览器可能会把属性值改掉,因为这两个浏览器共享同一个servletContext域。

 

Cookie API

1、javax.servlet.http.Cookie类用于创建一个

    CookieCookie c = new Cookie("lastTime",new Date().getTime()+"");

2response接口也中定义了一个addCookie方法,它用于在其响应头中增加一个相应的Set-Cookie头字段

c.setMaxAge(3600*24*30);
c.setPath(request.getContextPath());   
 response.addCookie(c);

 

3、同样,request接口中也定义了一个getCookies方法,它用于获取客户端提交的Cookie

Cookie[] cs = request.getCookies();
Cookie findc = null;
if(cs!=null){
for(Cookie cc:cs){
if("lastTime".equals(cc.getName())){
findc=cc;}
             }
Long  ltime = Long.parseLong(findc.getValue());

 

4Cookie类的方法:

 (1)*setMaxAgegetMaxAge方法  

如果创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除

若希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie

注意,删除cookie时,path必须一致,否则不会删除(浏览器通过cookiename+path来标识一个cookie)


(2)*setPathgetPath方法

1.用来通知浏览器在访问服务器中的哪个路径及其子路径时带着当前cookie信息过来

    2.如果不明确设置则默认的路径是发送CookieServlet所在的路径及其子路径。

                http://localhost/Day05/servlet/...

3.访问路径设置为当前web应用及其子路径

               c.setPath(request.getContextPath());   

 

(3)setDomaingetDomain方法

   用来通知浏览器在访问哪个域名的时候带着当前的cookie信息

但是要注意现代的浏览器一旦发现cookie设置过domain信息会拒绝接受这个Cookie我们平常不要设置这个方法

        

Cookie细节

1.一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)。

2.一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie

3.浏览器一般只允许存放300Cookie,每个站点最多存放20Cookie,每个Cookie的大小限制为4KB


Cookie案例_最后看过的书

Book.java

 bean包括id,name,auth,price等属性,get,set方法,空参构造方法,和带定义属性值的构造方法。

 

BookDao.java工具包

  1.私有化构造方法,构造Map来存书
private static Map<String,Book> bookMap = new LinkedHashMap<String, Book>();
  2.静态代码块
 static{
   bookMap.put("1", new Book("1","三国演义","99.0","朴乾","黑马出版社","一群...."));
   ......}
  3.提供获取书集bookMap方法
public static Map<String,Book> getBooks(){
return bookMap;
}
  4.提供获取书book的方法
public static Book getBook(String id){
return bookMap.get(id);
}

 

BookListServlet.java

//1.查询数据库中所有的书展示
Map<String,Book> map = BookDao.getBooks();
for(Map.Entry<String , Book> entry : map.entrySet()){
    Book book = entry.getValue();
....}
//2.显示之前看过的书
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>");
    }
}

BookInforServlet.java

//1.获取要看的书的id,查询数据库找出书,输出书的详细信息
String id = request.getParameter("id");
Book book = BookDao.getBook(id);
//2.发送cookie保存最后看过的书
String ids = "";   //new Cookie("last",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){
    //说明之前没有看过书的记录,先把现在这本书的id给存到ids里面
    ids += book.getId();
}else{
    //说明之前有历史看过的书的记录,需要根据历史记录算一个新的记录出来
    String [] olds = findC.getValue().split(","); 
    //弄个缓存,判断记录有没有超过3?新==老?
        StringBuffer buffer = new StringBuffer();
           //在缓存里,先存个新的
    buffer.append(book.getId()+",");
    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);
}