首页 > 代码库 > Cookie与Session

Cookie与Session

 

一、Cookie详解
    1、属性:
        name:(必须)
        value:(必须)不能是中文
        maxage:(可选)最长存活时间.默认是会话。单位是秒
        path:(可选)路径
            一个cookie的默认路径是:写cookie的那个servlet的访问路径。
            写cookie的servlet的路径是:String path = /day05_01_cookie/servlet/
                            如果访问的路径.startWith(path),浏览器就会把刚才写的cookie带给服务器。
        domain :(可选)域名
        comment:(可选)注释
        version:(可选)版本号
 
    2、服务器如何向客户端写Cookie:
        HttpServletResponse.addCookie(javax.servlet.http.Cookie)(实际上就是写了一个Set-Cookie的响应消息头)
        浏览器对于一个网站最多存20个cookie  (Cookie的个数是有限的)
        cookie总数不能超过300个。
        每个Cookie大小不能超过4KB。
    3、服务器如何取出客户端带来的cookie:HttpServletRequest.getCookies() (实际上就是获取 名字为cookie的请求消息头)
 
    4、如何唯一确定一个Cookie
        domain+path+name
        localhost/day05_01_cookie/servlet/   + lastAccessTime
Cookie案例
利用cookie技术记录用户最近一次访问的时间
技术分享
 public   void  doGet(HttpServletRequest  request , HttpServletResponse response)             throws  ServletException, IOException {        response.setContentType( "text/html;charset=UTF-8" );        PrintWriter out = response.getWriter();        out.write( "上次访问的时间是:" );         //得到指定的cookie,该cookie中记录了上次访问的时间        Cookie[] cs = request.getCookies();         for ( int  i=0;cs!= null &&i<cs. length ;i++){            Cookie c = cs[i];             if ( "lastTime" .equals(c.getName())){                String value = c.getValue();                 //把cookie里面字符串转成long,再由Date转成可读格式                 long  time = Long. parseLong (value);                String ti =  new  Date(time). toLocaleString() ;                out.write(ti);            }        }         //清除cookie        out.write( "<a href=http://www.mamicode.com/‘/my_exericse_day05/servlet/MyCookieDemo2‘>清除cookie" );         //把当前时间写入到cookie里面        Cookie cookie =  new  Cookie( "lastTime" , System. currentTimeMillis ()+ "" );         //设置cookie的存货时间,单位是秒.如果是Long单位多半是毫秒        cookie.setMaxAge(1*30*24*60*60);         //设置路径为当前应用的名称,意味着当前应用的任何资源都可以得到该cookie.        cookie.setPath(request.getContextPath());        response.addCookie(cookie);     }
最近一次访问的时间

删除指定的Cookie

 //删除指定的cookie     public   void  doGet(HttpServletRequest request, HttpServletResponse response)             throws  ServletException, IOException {        response.setContentType( "text/html;charset=UTF-8" );        PrintWriter out = response.getWriter();        Cookie c =  new  Cookie( "lastAccesTime" ,  "" ); //和上面的一样的        c.setMaxAge(0);        c.setPath(request.getContextPath());        response.addCookie(c);                out.write( "删除成功!" );     }

提供选项让用户设置是否记录登录名

技术分享
 //提供登陆界面     //显示记住的用户名     public   void  doGet(HttpServletRequest request, HttpServletResponse response)             throws  ServletException, IOException {        response.setContentType( "text/html;charset=UTF-8" );        PrintWriter out = response.getWriter();         //显示记住的用户名        String username =  "" ;        String checked =  "" ;         //找到指定的cookie        Cookie cs[] = request.getCookies();         for ( int  i=0;cs!= null &&i<cs. length ;i++){             if (CookieStatics. LOGIN_USERNAME .equals(cs[i].getName())){                 //找到了                String value =http://www.mamicode.com/ cs[i].getValue();                username = value;                checked =  "checked=‘checked‘" ;                 break ; //不希望程序继续往下运行            }        }                 //提供登陆界面        out.write( "<form action=‘" +request.getContextPath()+ "/servlet/LoginServletDemo2‘ method=‘post‘>" );        out.write( "用户名:<input type=‘text‘ name=‘username‘ value=http://www.mamicode.com/‘" +username+ "‘/><br/>" );        out.write( "密码:<input type=‘password‘ name=‘password‘/><br/>" );        out.write( "记住用户名:<input type=‘checkbox‘ name=‘remember‘ " +checked+ " /><br/>" );        out.write( "<input type=‘submit‘ value=http://www.mamicode.com/‘登陆‘/>" );        out.write( "</form>" );     }
记住登录名-1

 

技术分享
//验证用户名或密码     //根据用户是否需要记住用户名来处理cookie     //是:添加cookie     //否:删除cookie     public   void  doGet(HttpServletRequest request, HttpServletResponse response)             throws  ServletException, IOException {        response.setContentType( "text/html;charset=UTF-8" );        PrintWriter out = response.getWriter();         //验证用户名或密码        String username = request.getParameter( "username" );        String remember = request.getParameter( "remember" );         //根据用户是否需要记住用户名来处理cookie         //用一个借口,来定义一个常量。直接引用,不容易出错        Cookie c =  new  Cookie(CookieStatics. LOGIN_USERNAME , username);        c.setPath(request.getContextPath());         if (remember== null ){             //否:删除cookie            c.setMaxAge(0);        } else {             //是:添加cookie的失效时间为最大            c.setMaxAge(Integer. MAX_VALUE );        }        response.addCookie(c);        out.write( "登陆成功!" );     }
记住登陆名-2

记录用户的浏览记录

技术分享
//显示所有的书籍,并提供查看详细的链接//显示用户最近的浏览记录:保留3public   void  doGet(HttpServletRequest request, HttpServletResponse response)         throws  ServletException, IOException {    response.setContentType( "text/html;charset=UTF-8" );    PrintWriter out = response.getWriter();     //显示所有的书籍,并提供查看详细的链接    out.write( "本站有以下好书,欢迎选购:<br/>" );    Map<String, Book> books = BookDB. findAllBooks ();     for (Map.Entry<String, Book> me:books.entrySet()){        out.write(me.getValue().getName()+ "  <a href=http://www.mamicode.com/‘" +request.getContextPath()+ "/servlet/ShowBookDetailServlet?id=" +me.getValue().getId()+ "‘>详情</a><br/>" );    }     //显示用户最近的浏览记录:保留3   bookHistory=3-2-1    out.write( "<hr/>您最近的浏览记录:<br/>" );    Cookie cs[] = request.getCookies();     for ( int  i=0;cs!= null &&i<cs. length ;i++){        Cookie c = cs[i];         if ( "bookHistory" .equals(c.getName())){            String bookIds = c.getValue(); //3-2-1            String ids[] = bookIds.split( "\\-" );             for (String id:ids){                Book book = BookDB. findBookById (id);                out.write(book.getName()+ "<br/>" );            }             break ;        }    }      }
显示所有的书
技术分享
//显示书籍的详细内容//向客户端写cookie记录浏览历史public   void  doGet(HttpServletRequest request, HttpServletResponse response)         throws  ServletException, IOException {    response.setContentType( "text/html;charset=UTF-8" );    PrintWriter out = response.getWriter();     //显示书籍的详细内容    String bookId = request.getParameter( "id" );    out.write( "详情:" +BookDB. findBookById (bookId).toString());    out.write( "<br/><a href=http://www.mamicode.com/‘" +request.getContextPath()+ "/servlet/ShowAllBooksServlet‘>继续购物</a>" );     //向客户端写cookie记录浏览历史    String ids = makeIds(request,bookId); //用-分隔    Cookie c =  new  Cookie( "bookHistory" , ids);    c.setPath(request.getContextPath());    c.setMaxAge(Integer. MAX_VALUE );    response.addCookie(c);}//组织要写回的书的id//    当前情况                                    新看的书            应写回的id//    cookie一个都没有                                1                1//    cookie不为null,但没有bookHistory                1                1//    bookHistory=1                                2                2-1//    bookHistory=2-1                                1                1-2//    bookHistory=2-1                                3                3-2-1//    bookHistory=2-1-3                            3                3-2-1//    bookHistory=2-1-3                            4                4-2-1private  String makeIds(HttpServletRequest request, String bookId) {//        cookie一个都没有                                1                1    Cookie cs[] = request.getCookies();     if (cs== null ||cs. length ==0)         return  bookId;     //        cookie不为null,但没有bookHistory                1                1    Cookie bookHistoryCookie =  null ;     for (Cookie c:cs){         if ( "bookHistory" .equals(c.getName())){            bookHistoryCookie = c;             break ;        }    }     if (bookHistoryCookie== null ){         return  bookId;    }     //        bookHistory=1                                2                2-1//        bookHistory=2-1                                1                1-2//        bookHistory=2-1                                3                3-2-1         String id = bookHistoryCookie.getValue(); // 2-1         LinkedList<String> list =  new  LinkedList<String>(Arrays. asList (id.split( "\\-" ))); // 2 1          if (list.size()<3){         if (list.contains(bookId)){            list.remove(bookId);        }        list.addFirst(bookId);    } else {     //        bookHistory=2-1-3                            3                3-2-1//        bookHistory=2-1-3                            4                4-2-1         if (list.contains(bookId)){            list.remove(bookId);        } else {            list.removeLast();        }        list.addFirst(bookId);    }     //把list中的id组织成字符串     //3 2 1---->3-2-1    StringBuffer sb =  new  StringBuffer();     for ( int  i=0;i<list.size();i++){         if (i>0)            sb.append( "-" );        sb.append(list.get(i));    }     return  sb.toString(); }
处理
二、HttpSession原理详解
    HttpSession借助Cookie技术的。
 
    HttpSession getSession():服务器会根据用户带来的JSESSIONIDcookie的值,先查找。找到继续为你服务,没有找到,创建新的HttpSession对象。
    HttpSession getSession(boolean b):
                    b为true:效果同getSession()
                    b为false:只是查询。
 
HttpSession原理详解
    HttpSession借助Cookie技术的。
    HttpSession getSession():服务器会根据用户带来的JSESSIONIDcookie的值,先查找。找到继续为你服务,没有找到,创建新的HttpSession对象。
    HttpSession getSession(boolean b):
                    b为true:效果同getSession()
                    b为false:只是查询。
 

技术分享

HttpSession的案例

    1、简单的不能再简单的购物车(先建立JavaBean,然后JavaBeanDB)
            浏览器关闭了,会话结束了。但是服务器端原来为您服务的HttpSession对象并没有消失(等待超时,默认30分钟)
技术分享
//显示所有的产品。提供购买和显示已买产品的链接public   void  doGet(HttpServletRequest request, HttpServletResponse response)         throws  ServletException, IOException {    response.setContentType( "text/html;charset=UTF-8" );    PrintWriter out = response.getWriter();    request.getSession();    out.write( "本站有以下好书:<br/>" );    Map<String, Book> books = BookDB. findAllBooks ();     for (Map.Entry<String, Book> me:books.entrySet()){        String url = request.getContextPath()+ "/servlet/BuyServlet?id=" +me.getKey();        url = response.encodeURL(url);        out.write(me.getValue().getName()+ "  <a href=http://www.mamicode.com/‘" +url+ "‘>购买</a><br/>" );    }    String url = request.getContextPath()+ "/servlet/ShowCartServlet" ;    url = response.encodeURL(url);    out.write( "<hr/><a href=http://www.mamicode.com/‘" +url+ "‘>显示已购买商品</a>" ); }
显示
技术分享
//购买 Servlet :把购买的书籍放入购物车(容器)。提供继续购物的链接public   void  doGet(HttpServletRequest request, HttpServletResponse response)         throws  ServletException, IOException {    response.setContentType( "text/html;charset=UTF-8" );    PrintWriter out = response.getWriter();    String id = request.getParameter( "id" );    Book book = BookDB. findBookById (id);     //放入购物车:一个客户端只有一个购物车,且不能被替换    HttpSession session = request.getSession();    List<Book> cart =  (List<Book>) session.getAttribute( "cart" ) ;     if (cart== null ){        cart =  new  ArrayList<Book>();        session.setAttribute( "cart" , cart);    }    cart.add(book);    String url = request.getContextPath()+ "/servlet/ShowProductServlet" ;    url = response.encodeURL(url);    out.write(book.getName()+ "已放入您的购物车!<a href=http://www.mamicode.com/‘" +url+ "‘>继续购物</a>" ); }
处理
技术分享
//显示购物车中的内容public   void  doGet(HttpServletRequest request, HttpServletResponse response)         throws  ServletException, IOException {    response.setContentType( "text/html;charset=UTF-8" );    PrintWriter out = response.getWriter();     //getSession()等于getSession(true),如果有Session,则返回,如果没有则创建.     //getSession(false),如果有Session,则返回,如果没有Session,则返回null    HttpSession session = request.getSession( false );     if (session== null ){        out.write( "哥们,你TMD真有才,什么都木有买就看看,SB" );         return ;    }     //session肯定创建过了:需要进一步显示    out.write( "您购买的商品如下:<br/>" );    List<Book> cart =  (List<Book>) session.getAttribute( "cart" ) ;     if (cart== null ){        out.write( "您还没有购买任何商品" );    } else         for (Book b:cart){            out.write(b.getName()+ "<br/>" );        }    String url = request.getContextPath()+ "/servlet/ShowProductServlet" ;    url = response.encodeURL(url);    out.write( "<a href=http://www.mamicode.com/‘" +url+ "‘ target=‘_blank‘>继续购物</a>" ); } 
显示购物车内容
2、完成用户登陆和一次性的验证码验证
建立一个JavaBean,存用户信息
建立一个ImageServlet,验证图片
建立登录HTML页面
技术分享
  < form   action = "/day06_00_session/servlet/LoginServlet"   method = "post" >        用户名: < input   type = "text"   name = "username" />< br />        密码: < input   type = "password"   name = "password" />< br />        验证码: < input   type = "text"   name = "code"   size = "4" />< img   id = "code"   src = "/day06_00_session/servlet/ImageServlet" />         < a   href = "javascript:changeNum()" > 看不清 </ a >         < br />         < input   type = "submit"   value = "登陆" />     </ form >     < script   type = "text/javascript" >        function  changeNum(){             //alert("haha");             //地址如果相同,浏览器不会发出请求            document.getElementById( "code" ).src= "http://www.mamicode.com/day06_00_session/servlet/ImageServlet?" + new  Date().getTime();        }      </ script >
页面
技术分享
//用户登陆public   void  doGet(HttpServletRequest request, HttpServletResponse response)         throws  ServletException, IOException {    request.setCharacterEncoding( "UTF-8" );    response. setContentType ( "text/html;charset=UTF-8" );    PrintWriter out = response.getWriter();     //验证“验证码”是否正确:从session中取出,与用户提交过来的参数进行对比    HttpSession session = request.getSession();    String sCode = (String) session.getAttribute( "code" );    String pCode = request.getParameter( "code" );     if (!pCode.equalsIgnoreCase(sCode)){        response.setHeader( "Refresh" ,  "2;URL=" +request.getContextPath()+ "/login.html" );        out.write( "验证码有误!2秒后自动转向登陆页面" );         return ;    }     //验证用户名和密码    User user =  new  User();    user.setUsername(request.getParameter( "username" ));    session.setAttribute( "user" , user);    response.setHeader( "Refresh" ,  "2;URL=" +request.getContextPath()+ "/servlet/IndexServlet" );    out.write( "登陆成功!2秒后转向主页" ); }
用户登录
技术分享
//模拟默认主页public   void  doGet(HttpServletRequest request, HttpServletResponse response)         throws  ServletException, IOException {    response.setContentType( "text/html;charset=UTF-8" );    PrintWriter out = response.getWriter();    HttpSession session = request.getSession();    User user = (User)session.getAttribute( "user" );     if ( user == null ){        out.write( "<a href=http://www.mamicode.com/‘" +request.getContextPath()+ "/login.html‘>登陆</a>" );    } else {        out.write( "欢迎您:" +user.getUsername()+ "  <a href=http://www.mamicode.com/‘" +request.getContextPath()+ "/servlet/LogoutServlet‘>注销</a>" );    }    out.write( "<hr/>这是主页内容" ); }
主页
技术分享
//注销public   void  doGet(HttpServletRequest request, HttpServletResponse response)         throws  ServletException, IOException {    HttpSession session = request.getSession();    session.invalidate(); //立即失效 }
注销

   3、防止表单重复提交

原理图:
技术分享

   MD5加密

技术分享
public   static  String md5Encode(String str){     try  {         //返回实现指定摘要算法的 MessageDigest 对象        MessageDigest md = MessageDigest. getInstance ( "md5" );         //进行MD5编码         byte  b[] = md.digest(str.getBytes()); //得到加密后的字节码         //把b字节码转换成字符串        BASE64Encoder base64 =  new  BASE64Encoder();         return  base64.encode(b);    }  catch  (NoSuchAlgorithmException e) {         throw   new  RuntimeException(e);    } }
加密
客户端禁用Cookie后的会话数据保存:URL重写
    解决办法:
    1、主页提示:为了更好的浏览本网站,请不要禁用您的cookie
    2、URL重写:很麻烦。必须对网站的所有地址都重写。
    重写后有以下效果:
        http://localhost:8080/day06_00_session/servlet/ShowCartServlet
        http://localhost:8080/day06_00_session/servlet/ShowCartServlet;JSESSIONID=sessionId
        用户禁用后,可以用一下方法重写地址。
        String response.encodeURL(String url); 自动判断用户有无禁用cookie,禁用了,重写。没有禁用,就不重写了。
 
 
HttpSession对象的状态转换(要实现Serializable接口,以序列化.?)
关闭session的两种方式:
1,在web.XML中进行一下配置,更改session保持时间,到时间就会被干掉。
<session-config>
      <session-timeout>1</session-timeout><!-- 1分钟,默认30分钟 -->
  </session-config>
2,session.invalidate();语句
 技术分享
 
IE浏览器何时才会开启一次新的会话
    1、IE8+:开启一个新的浏览器进程,都是一次会话。
    2、开启选项卡或者在新窗口中打开新页面都是同一此会话。
 
    3、开启新会话:“文件”-->"新建会话"
 

Cookie与Session