会话:
客户端和服务器之间从建立连接到一方断开之间的多次请求和响应。
会话技术包括:
- 客户端会话技术 cookie
- 服务端会话技术 session
本篇讲解客户端会话技术。
cookie 对象在服务器端创建,然后通过响应对象发送给客户端(浏览器),并保存在客户端浏览器中,默认是浏览器关闭时cookie自动删除。
cookie简单代码实现:
@WebServlet("/servletCookie") public class ServletCookie extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cookie cookie = new Cookie("name", "zhangsan");//设置cookie response.addCookie(cookie); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }
@WebServlet("/servletCookieDemo2") public class ServletCookieDemo2 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cookie[] cookies = request.getCookies(); for (Cookie cookie : cookies) { String name = cookie.getName(); String value = cookie.getValue(); System.out.println(name + " " + value); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }
下面讨论一下关于cookie的一些细节问题:
-
cookie的实现原理
-
cookie在浏览器中保存多长时间
-
cookie能不能存中文
-
cookie的共享范围
-
浏览器对于cookie的大小和数量
1.cookie的实现原理:
但浏览器创建cookie对象并赋值响应给浏览器的时候会在响应头中会存在set-cookie:name=zhangsan(沿用上面代码的案例)的响应头,浏览器就收到这样的响应头就会在本地保存这个cookie,然后浏览器下次访问服务器的时候就会在请求头信息中存在:cookie:name=zhangsan的请求头信息,通过request对象的getCookies();方法可以获得cookie数组。图解如下:
通过浏览器开发者工具对上述过程进行验证:
访问ServletCookie的响应头中:
访问ServletCookieDemo2:
2.cookie在浏览器中保存多长时间:
(1)默认情况下当浏览器关闭的时候cookie会被自动删除:
(2)持久化存储在浏览器:通过cookie对象的方法setMaxAge(int Seconds);
-
-
- 参数默认是-1:表示关闭浏览器是删除cookie
- 参数为0:表示删除cookie
- 参数为正整数: 表示在多少秒之后删除cookie
-
代码演示:
@WebServlet("/servletCookie") public class ServletCookie extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cookie c1 = new Cookie("name", "zhangsan");//设置cookie c1.setMaxAge(60*5);//保存5分钟后自动删除 response.addCookie(c1); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }
访问 ServletCookie之后关闭浏览器
当打开浏览器之后访问servletCookieDemo2依然会打印:
3.cookie能不能存中文
- tomCat8之前不能直接存中文(结局办法:使用URL编码)
- tomCat8之后可以存中文(不包括特殊字符,比如空格)
代码演示:
@WebServlet("/servletCookie") public class ServletCookie extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cookie c1 = new Cookie("name", "张三");//设置cookie response.addCookie(c1); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }
访问资源类2正常打印:
但是cooki的键还是不支持中文,会报错:
@WebServlet("/servletCookie") public class ServletCookie extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cookie c1 = new Cookie("姓名", "张三");//设置键时中文 response.addCookie(c1); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }
访问报错:
解决办法一样是使用URL编码:
传值钱使用URL编码
@WebServlet("/servletCookie") public class ServletCookie extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String encode = URLEncoder.encode("姓名", "utf-8"); //编码 Cookie c1 = new Cookie(encode, "张三");//设置键时中文 response.addCookie(c1); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }
收值后使用URL解码
@WebServlet("/servletCookieDemo2") public class ServletCookieDemo2 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cookie[] cookies = request.getCookies(); if (cookies!=null){ for (Cookie cookie : cookies) { String name = cookie.getName(); String value = cookie.getValue(); name=URLDecoder.decode(name,"utf-8"); //解码 System.out.println(name + " " + value); } } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }
正常打印:
4.cookie的共享范围:
1.cookie的共享范围是默认是当前项目,我们可以通过cookie对象的setPath(String path);方法进行设置
当设置"/"的时候是整个服务器共享。
2. 不同服务器之间cookie能不能共享?
可以共享但是要设置通过cookie对象的setDoMain(String path);的方法,如果path代表的是以及域名,那么不同服务器的一级域名相同的可以共享
例如:百度贴吧和百度新闻之间的共享
5.浏览器对于cookie的大小和数量
一个cookie大小大约为4kb,同一域名下的cookie数量不得超过大约20个