一.会话概述
1.1 什么是会话
http协议是一个无状态协议,同一会话的多次请求相互独立,会话负责存储浏览器和服务器多次请求之间的数据
1.2 会话技术
客户端会话技术:Cookie
服务端会话技术:Session
二.Cookie
2.1 概述
作用:在一次会话的多个请求之间共享数据,将数据保存到客户端
2.2 快速入门
2.2.1 设置数据到Cookie中
创建cookie对象,设置数据
Cookie cookie = new Cookie(String name,String value);
通过response,响应(返回)cookie
response.addCookie(cookie);
2.2.2 从cookie中获取数据
通过request对象,接收cookie数组
Cookie[] cookies = request.getCookies()
遍历数组
for(Cookie cookie:cookies){
}
浏览器具有自动存储cookie的能力,也有请求携带cookie的能力
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| @WebServlet("/SetServlet") public class SetServlet 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 = new Cookie("name","jack"); resp.addCookie(cookie); } }
@WebServlet("/GetServlet") public class GetServlet 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[] cookies = req.getCookies(); if (cookies != null) { for (Cookie cookie : cookies) { String name = cookie.getName(); String value = cookie.getValue(); System.out.println(name+"="+value); } } } }
|
2.3 工作原理
基于HTTP协议:请求头cookie和响应头set-cookie
2.4 Cookie细节
2.4.1 服务器如何发送多个Cookie
创建多个cookie对象
Cookie cookie1 = new Cookie(“name”,”rose”);
Cookie cookie2 = new Cookie(“age”,”18”);
通过response响应多个cookie
response.addCookie(cookie1);
response.addCookie(cookie2);
1 2 3 4 5 6 7 8 9 10 11 12 13
| @WebServlet("/MultipleCookie") public class MultipleCookie 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 = new Cookie("name", "rose"); Cookie age = new Cookie("age", "18"); resp.addCookie(cookie); resp.addCookie(age); }
|
}
2.4.2 Cookie在浏览器的保存时间
默认情况下,浏览器关闭(会话结束),cookie销毁(浏览器内存中存储)
设置Cookie的存活时间
cookie.setMaxAge(int second);
正数:指定存活时间,持久化浏览器的磁盘中,到期后自动销毁
负数:默认浏览器关闭,cookie销毁
零:立即销毁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| @WebServlet("/MaxAgeCookie") public class MaxAgeCookie 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 = new Cookie("product", "MI"); cookie.setMaxAge(0); resp.addCookie(cookie); } }
|
2.4.3 Cookie是否支持中文存储
Tomcat 8版本开始支持中文
但是不支持部分特殊字符,如:分号,空格,逗号等,会触发Rfc6265 CookieProcessor规范错误
建议使用通用方法存储字符
URLEncoder 编码
URLDecoder 解码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| @WebServlet("/EncodeCookie") public class EncodeCookie 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 { String product = ("华为 30X,"); product= URLEncoder.encode("UTF-8"); Cookie cookie = new Cookie("Brand", "苹果"); Cookie cookie1 = new Cookie("product", product); resp.addCookie(cookie); }}
@WebServlet("/GetServlet") public class GetServlet 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[] cookies = req.getCookies(); if (cookies != null) { for (Cookie cookie : cookies) { String name = cookie.getName(); String value = cookie.getValue(); value = URLDecoder.decode("UTF-8"); System.out.println(name + "=" + value); } } }}
|
2.4.4 Cookie共享数据的范围
2.4.4.1 同一个Tomcat服务器中,部署多个web项目,能否共享Cookie
默认情况下不可以
默认Cookie的携带路径,是当前设置cookie的servlet父路径
设置Cookie:http://localhost:8080/Day36_war_exploded/EncodeCookie
默认携带路径:http://localhost:8080/Day36_war_exploded/
指定Cookie携带路径
cookie.setPath(String Path);
例:cookie.setPath(“/“);
/ 相当于http://localhost:8080/
此cookie携带路径
http://localhost:8080/
访问:
http://localhost:8080/Day36_war_exploded/
http://localhost:8080/Day35_war_exploded/
携带路径不同,可以存储同名的cookie
在当前项目下共享cookie方法
cookie.setPath(“/项目名”);
2.4.4.2 不同Tomcat服务器之间的Cookie能否共享
默认情况下不可以
多个服务器之间的数据共享cookie,需要在同一个一级域名下
cookie.setDomain(“.xx.com”)
2.5 Cookie特点
Cookie存储的数据都在客户端
Cookie存储的数据只能是字符串
Cookie单个大学不能超过4kb
同一个域名下Cookie的数量不能超过50个
Cookie路径不同,可以重名出现
Cookie存储数据不太安全
三.综合案例
3.1 用户上次访问记录
需求:访问一个Servlet,如果是第一次访问,则提示:”您好”,如果不是,则提示”上次访问时间”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| public class CookieUtils { public static Cookie findByName(String name, Cookie[] cookies) { if (cookies != null && cookies.length > 0) { for (Cookie cookie : cookies) { if (name.equals(cookie.getName())) { return cookie; } } } return null; } } @WebServlet("/LastTimeServlet") public class LastTimeServlet 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 { resp.setContentType("text/html;charset=UTF-8"); Cookie cookie = CookieUtils.findByName("last_time", req.getCookies()); if (cookie == null) { resp.getWriter().write("Welcome"); } else { String value = cookie.getValue(); resp.getWriter().write("Welcome Back,Last Visit Time:" + value); } SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd-HH:mm:ss"); String currentTime = simpleDateFormat.format(new Date()); cookie = new Cookie("last_time", currentTime); cookie.setMaxAge(60*60*24*365); resp.addCookie(cookie); } }
|
3.2 JSP初体验
Java服务端页面
简单来说:一个特殊的页面,即可定义html标签,又可定义Java代码
作用:简化书写,展示动态页面
本质:Servlet
脚本:JSP通过脚本方式来定义Java代码
<% Java代码 %> 就相当于Servlet中service方法
内置对象:在JSP页面中不需要获取和创建,可以直接使用对象
request
response
out
在JSP中响应内容,使用out
tomcat优先解析response缓冲区内容,再解析out缓冲区内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html>
<head> <title>Demo</title> </head>
<body>
<h3>I am Title</h3> <table border="1" width="300" align="center"> <tr> <td>I am static resource</td>
</tr>
</table> <%
System.out.println("I am jsp"); out.write("Out"); %> </body> </html>
|
3.3 商品浏览记录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <body>
<h3>List</h3>
<a href="/Day36_war_exploded/GoodsInfoServlet?name=MI">MI</a><br> <a href="/Day36_war_exploded/GoodsInfoServlet?name=HW">HW</a><br> <a href="/Day36_war_exploded/GoodsInfoServlet?name=Apple">Apple</a><br> <a href="/Day36_war_exploded/GoodsInfoServlet?name=TCL">TCL</a><br> </body>
<body> <% Cookie cookie = CookieUtils.findByName("goods_name", request.getCookies()); if (cookie == null) { out.write("No History"); } else { String value = cookie.getValue(); for (String product : value.split("-")) { out.write(product + "<br/>"); } } %> </body>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| @WebServlet("/GoodsInfoServlet") public class GoodsInfoServlet 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 { req.setCharacterEncoding("utf-8"); resp.setContentType("text/html;charset=utf-8"); String product = req.getParameter("name"); resp.getWriter().write("It's " + product); Cookie cookie = CookieUtils.findByName("goods_name", req.getCookies());
if (cookie == null) { cookie = new Cookie("goods_name", product); } else { String value = cookie.getValue(); List<String> list = Arrays.asList(value.split("-")); if (!list.contains(product)) { value=value+"-"+product; } cookie = new Cookie("goods_name", value); } cookie.setMaxAge(10); resp.addCookie(cookie);
resp.getWriter().write("<br/><a href='/Day36_war_exploded/goods.html'>Continue View</a><br/>"); resp.getWriter().write("<a href='/Day36_war_exploded/history.jsp'>History</a><br/>"); } }
|