Cookie与HttpSession对象
Cookie与HttpSession对象的作用
维护客户端浏览器与服务端会话状态的两个对象。
- 由于HTTP协议是一个无状态的协议,因此服务端不会记录当前客户端浏览器的访问状态
- 有些时候需要服务端能够记录当前客户端浏览器的访问状态,如:获取当前客户端浏览器访问服务端的次数时就需要会话状态的维持
- Servlet当中提供了Cookie对象与HttpSession对象用于维护客户端与服务端的会话状态的维持
- 二者不同的是Cookie是通过客户端浏 览器实现会话的维持,而HttpSession是通过服务端来实现会话状态 的维持。
Cookie对象的特点
- 使用字符串存储数据
- 使用Key与Value结构存储数据
- 单个Cookie存储数据大小限制在4097个字节
- Servlet4.0前存储的数据不支持中文,Servlet4.0后支持
- Cookie与域名绑定因此不支持跨一级域名访问
- Cookie对象保存在客户端浏览器的内存或系统磁盘中
- 分为持久化Cookie和状态Cookie
- 浏览器在保存同一域名所返回Cookie的数量是有限的,不同浏览器支持的数量不同,Chrome浏览器为50个
- 浏览器每次请求时都会把与当前访问的域名相关的Cookie在请求中提交到服务端
Cookie对象的创建与写回
- Cookie cookie = new Cookie("key","value")
通过new关键字创建Cookie对象
- response.addCookie(cookie)
通过HttpServletResponse对象将Cookie写回给客户端浏览器。
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebServlet("/creatcookie") public class CreatCookie extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //创建cookie对象 Cookie cookie=new Cookie("key","value"); //将cookie写回给客户端浏览器 resp.addCookie(cookie); //创建响应流对象 PrintWriter pw=resp.getWriter(); //将结果返回给客户端浏览器 pw.println("cookie creat successfull"); } }

 
获取Cookie对象的数据
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebServlet("/getdata") public class GetCookieData extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取所有cookie对象 Cookie[] cookies=req.getCookies(); //响应输出流 PrintWriter pw=resp.getWriter(); for (int i=0;i<cookies.length;i++){ //获取每个cookie的name String name=cookies[i].getName(); //获取每个cookie的value String value=cookies[i].getValue(); //输出到客户端 pw.println("name:"+name+"value:"+value); } //刷新流 pw.flush(); //关闭流 pw.close(); } }
解决cookie不支持中文的问题
cookie中的name值不能使用中文,value可以,但Servlet4.0版本前cookie中的value也不支持中文存储,如果存储的数据含有中文,代码会出现异常

通过对含有中文数据重新进行编码来解决该问题
- URLEncoder.encode("content","code")
将内容按照指定的编码方式做URL编码处理。
- URLDecoder.decode("content","code")
将内容按照指定的编码方式做URL解码处理。
Cookie的跨境问题
域名分类
顶级域、顶级域名(一级域名)、二级域名

域名等级的区别
1)一级域名比二级域名更高级
2)二级域名是一级域名的细化分级(二级域名依附于一级域名之下的附属分区域名)
3)baidu.com为一级域名,news.baidu.com为二级域名
Cookie不支持一级域名的跨域,支持二级域名的跨域

持久化Cookie与状态Cookie
- 状态Cookie:
Cookie对象仅会被缓存在浏览器所在的内存中。当浏 览器关闭后Cookie对象 也会被销毁。
- 持久化Cookie:
浏览器会对Cookie做持久化处理,基于文件形式保存在系统的指定目录中(不仅保存在内存中,也保存在系统的指定磁盘中)。在Windows10系统中为了安全问题不会显 示Cookie中的内容。
如何将状态cookie转为持久化cookie
当Cookie对象创建后默认为状态Cookie。可以使用Cookie对象下的 cookie.setMaxAge(60)方法设置失效时间,单位为秒。一旦设置了失效时间,那么该Cookie为持久化Cookie,浏览器会将Cookie对象持久化到磁盘中。当失效时间到达后文件删除。
通过Cookie实现客户端与服务端会话的维持
当客户端浏览器第一次访问Servlet时响应“您好,欢迎您第一 次访问!”,第二次访问时响应“欢迎您回来!”。
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; /** * 当客户端浏览器第一次访问Servlet时响应“您好,欢迎您第一 * 次访问!”,第二次访问时响应“欢迎您回来!”。 */ @WebServlet("/welcome") public class Welcome extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //设置响应编码 resp.setContentType("text/plain;charset=utf-8"); //获取客户端的所有cooike Cookie[] cookies=req.getCookies(); //当flag为true表明是第一次,为false表明第二次 Boolean flag=false; for (Cookie c:cookies) { if ("welcome".equals(c.getName())){ //找到了第一次访问的cookie,将标志位设为true flag=true; //退出循环 break; } } //获取响应输出流 PrintWriter pw=resp.getWriter(); //不是第一次访问 if (flag){ pw.println("欢迎您回来!"); }else { //如果是第一次访问,则创建名为welcome的cookie Cookie cookie=new Cookie("welcome","第一次访问"); cookie.setMaxAge(3000); //将welcomecookie响应给客户端 resp.addCookie(cookie); pw.println("欢迎您第一次访问!"); } } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req,resp); } }
Cookie总结
Cookie对于存储内容是基于明文的方式存储的,所以安全性很低。 不要在Cookie中存放敏感数据。在数据存储时,虽然在Servlet4.0 中Cookie支持中文,但是建议对Cookie中存放的内容做编码处理, 也可提高安全性。
HttpSession对象的特点
- HttpSession保存在服务端
- HttpSession使用key与value结构存储数据
- HttpSession的key是字符类型,Value是Object类型
- HttpSession存储数据大小无限制
HttpSession对象的创建
HttpSession对象的创建是通过request.getSession()方法来创建的。
- 客户端浏览器在请求服务端资源时,如果在请求中没有 jsessionid的Cookie,getSession()方法将会为这个客户端浏览器创建一个新的HttpSession对象,并为这个HttpSession对象生成一个 jsessionid,在响应中通过状态Cookie写回给客户端浏览器,
- 如果在请求中包含了jsessionid,getSession()方法则根据这个ID返回与这个客户端浏览器对应的HttpSession对象。
getSession()方法还有一个重载方法getSession(true|false)。当参数为true时与getSession()方法作用相同。当参数为false时则只去根据jsessionid查找是否有与这个客户端浏览器对应的 HttpSession,如果有则返回,如果没有jsessionid则不会创建新的 HttpSession对象。![]() HttpSession对象的使用
HttpSession对象的使用
- session.setAttribute("key",value)
将数据存储到HttpSession对象中
- Object value = session.getAttribute("key")
根据key获取HttpSession中的数据,返回Object
- Enumeration attributeNames = session.getAttributeNames()
获取HttpSession中所有的key,返回枚举类型
- session.removeAttribute("key")
根据key删除HttpSession中的数据
- String id = session.getId()
根据获取当前HttpSession的SessionID,返回字符串类型
HttpSession的销毁方式
1)通过web.xml指定超时时间
- 在web.xml文件中指定HttpSession的超时时间
    <session-config>
        <session-timeout>2</session-timeout>
    </session-config>
- 当到达指定的超时时间后,容器就会销毁该HttpSession对象,单位为分钟。
- 该时间对整个web项目中的所有HttpSession对象有效。
- 时间的计算方式是根据最后一次请求时间作为起始时间。只要用户继续访问, 服务器就会更新HttpSession的最后访问时间,并维护该HttpSession。
- 用户每访问服务器一次,无论是否读写 HttpSession,服务器都认为该用户的HttpSession"活跃 (active)"了一次,销毁时间则会重新计算。
- 如果有哪个客户端浏览器对应的HttpSession的失效时间已到,那么与该客户端浏览器对应的HttpSession对象就会被销毁。其他客户端浏览器对应的 HttpSession对象会继续保存不会被销毁。
也可以在Tomcat的web.xml文件中配置HttpSession的销毁时间。如果在Tomcat的web.xml文件中配置了HttpSession的超时时 间对应的是Tomcat中所有的Web项目都有效。相当于配置了全局的HttpSession超时时间。如果我们在Web项目中配置了超时时间, 那么会以Web项目中的超时时间为准。

2)通过HttpSession对象中的invalidate()方法销毁当前HttpSession对象
通过HttpSession实现客户端与服务端会话的维持
当客户端浏览器第一次访问Servlet时响应“第一 次访问!”,第二次访问时响应“欢迎回来!”。
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //设置响应编码 resp.setContentType("text/html;charset=utf-8"); //当参数为false时则只去根据jsessionid查找是否有与这个客户端浏览器对应的HttpSession, //如果有则返回,如果没有jsessionid则不会创建新的HttpSession对象。 HttpSession session=req.getSession(false); //获取响应输出流 PrintWriter pw=resp.getWriter(); Boolean flag=false; //获取的session为空,说明是第一次访问,则为客户端创建一个session if (session==null){ flag=true; req.getSession(true); } if (flag){ pw.println("第一次访问!"); }else { pw.println("欢迎回来!"); } //刷新 pw.flush(); //关闭 pw.close(); }
HttpSession生命周期
1)HttpSession对象的生命周期没有固定的创建时间和销毁时间
2)创建时间取决于第一次调用getSession()或getSession(true)的方法
3)销毁时间取决于超时时间的到达以及invalidate()方法的调用
4)如果没有超时也没有调用invalidate()方法,那么HttpSession会一直存储
5)默认的超时时间为30分钟
HttpSession与Cookie的区别
- cookie数据存储在客户的浏览器或者系统中,HttpSession的数据存放在服务器中
- cookie不安全,HttpSession是安全的
- 单个cookie保存的数据不能超过4K,很多浏览器都限制一个域名保存cookie的数量。而 HttpSession没有容量以及数量的限制。
HttpSession的使用建议
HttpSession对象是保存在服务端的,所以安全性较高。可以在 HttpSession对象中存储数据,但是由于HttpSession对象的生命周期不固定,所以不建议存放业务数据。一般情况下我们只是存放用户登录信息。
 
                     
                    
                 
                    
                

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号