首页 > 代码库 > 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>" ); }
//验证用户名或密码 //根据用户是否需要记住用户名来处理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( "登陆成功!" ); }
记录用户的浏览记录
//显示所有的书籍,并提供查看详细的链接//显示用户最近的浏览记录:保留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
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。