会话技术介绍
- 为什么?
- ServletRequest域对象共享范围太小了,ServletContext域对象共享范围太大了。
- 概述
- 指的是web开发中的一次通话过程,当打开浏览器,访问网站地址后,会话开始,当关闭浏 览器(或者到了过期时间),会话结束。
- 作用
- 存储数据并实现共享
- 分类
- Cookie : 浏览器端会话技术
- Session : 服务器端会话技术
cookie概述
- 概述
- 它是客户端浏览器的缓存文件,里面记录了客户浏览器访问网站的一些内容。同时,也是 HTTP协议请求头(Cookie)和响应头(Set-Cookie)的一部分
- 作用
- 它可以保存客户浏览器访问网站的相关内容(需要客户端不禁用Cookie)。从而在每次访问 需要同一个内容时,先从本地缓存获取,使资源共享,提高效率。
- 常用属性
- name : cookie名称
- value : cookie值
- path : cookie访问路径
- maxAge : cookie存活时长
cookie的基本使用
- 需求
- ①创建Cookie对象
- ②将Cookie对象返回给浏览器并保存
- ③获取Cookie对象
- 代码实现
@WebServlet("/demo01")
public class Demo01Servlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//①创建Cookie对象
String msg = "hello";
Cookie cookie = new Cookie("msg",msg);
//②将Cookie对象返回给浏览器并保存
response.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
@WebServlet("/demo02")
public class Demo02Servlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//③获取Cookie对象
Cookie myCookie = null;//记录自己的Cookie对象
Cookie[] cookies = request.getCookies();
if (null != cookies && 0 != cookies.length) {
for (Cookie cookie : cookies) {
if ("msg".equals(cookie.getName())) {
myCookie = cookie;
}
}
}
if (null != myCookie) {
System.out.println("name : " + myCookie.getName() + " , value : " + myCookie.getValue());
} else {
System.out.println("没有找到自己的cookie");
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
cookie的执行流程
执行流程
- ①浏览器发起第一次请求Demo01Servlet(msg)
- 创建Cookie对象(name=msg,value=hello)
- 通过Set-Cookie响应头将Cookie对象携带回浏览器
- ②浏览器发起第二次请求Demo02Servlet(msg)
- 通过Cookie请求头将Cookie对象信息携带到服务器
cookie的相关设置
- 值限制
- Cookie 的值不能包含逗号、分号、空格,不能以$开头。
- 存活时长限制 : setMaxAge
- -1 : 默认值,浏览会话结束时
- 0 :立即销毁
- 正数:设置cookie存活时长,以秒为单位
- 访问路径限制 : setPath
- 默认情况下,是"/项目访问路径",访问项目下所有资源都会携带Cookie
- 完全匹配
- 比如 : “/web15/xyz/index.html” , 只有"/web15/xyz/index.html"才会携带cookie
- 目录匹配
- 比如:"/web15/xyz","/web15/xyz/index.html"、"/web15/xyz/demo01.html"都 会携带cookie
cookie的销毁
- 开发步骤
- ①创建Cookie对象
- 设置相同的名称
- ②设置相同的访问路径
- ③设置maxAge=0
- ①创建Cookie对象
- 代码实现
@WebServlet("/demo06")
public class Demo06Servlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie cookie = new Cookie("msg3", "hello3");
cookie.setPath("/");
response.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
@WebServlet("/demo07")
public class Demo07Servlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//①创建Cookie对象
Cookie cookie = new Cookie("msg3", "helloworld");
//②设置相同的访问路径
cookie.setPath("/");
//③设置maxAge=0
cookie.setMaxAge(0);
response.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
cookie的练习
- 需求
- 显示商品浏览记录
- 开发步骤
- ①引入thymeleaf运行环境
- 引入thymeleaf相关jar包
- 在web.xml中,配置视图前缀、视图后缀
- 引入ViewBaseServlet
- 引入ModelBaseServlet
- ②编写shopping.html
- 展示商品列表
- ③编写ShoppingServlet
- addShoppingHistory : 添加商品浏览记录
- showShoppingHistory : 获取商品浏览记录
- ④编写shopping_history.html
- 展示商品浏览记录
- ①引入thymeleaf运行环境
- ②编写shopping.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>商品列表</title>
</head>
<body>
<a th:href="@{/shopping(method=addShoppingHistory,id=0)}">西游记</a><br>
<a th:href="@{/shopping(method=addShoppingHistory,id=1)}">红楼梦</a><br>
<a th:href="@{/shopping(method=addShoppingHistory,id=2)}">水浒传</a><br>
<a th:href="@{/shopping(method=addShoppingHistory,id=3)}">三国演义</a><br>
<a th:href="@{/shopping(method=showShoppingHistory)}">查看浏览记录</a>
</body>
</html>
③编写ShoppingServlet
@WebServlet("/shopping")
public class ShoppingServlet extends ModelBaseServlet {
/**
* 转发到shopping.html
*
* @param request
* @param response
*/
public void toShoppingPage(HttpServletRequest request, HttpServletResponse response) {
System.out.println("toShoppingPage");
try {
processTemplate("shopping", request, response);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 添加商品浏览记录
*
* @param request
* @param response
*/
public void addShoppingHistory(HttpServletRequest request, HttpServletResponse response) {
System.out.println("addShoppingHistory");
String id = request.getParameter("id");
System.out.println("id = " + id);
//①判断是否是第一次请求
Cookie historyCookie = null;//记录自己的Cookie
Cookie[] cookies = request.getCookies();
if (null != cookies && 0 != cookies.length) {
for (Cookie cookie : cookies) {
if ("history".equals(cookie.getName())) {
historyCookie = cookie;
}
}
}
if (null == historyCookie) {
//是第一次请求
historyCookie = new Cookie("history", id);
} else {
//不是第一次请求,判断商品之前是否有浏览过?
//获取上一次浏览记录
String historyStr = historyCookie.getValue();
if (!historyStr.contains(id)) {
//没有浏览过该商品,直接拼接
historyStr = historyStr + "-" + id;
} else {
//有浏览过该商品,不处理
}
historyCookie.setValue(historyStr);
}
//将新的cookie返回给浏览器保存
response.addCookie(historyCookie);
//添加浏览记录完成之后,要展示浏览记录 (重定向)
try {
response.sendRedirect(request.getContextPath() + File.separator + request.getServletPath() + "?method=showShoppingHistory");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 展示商品浏览记录
*
* @param request
* @param response
*/
public void showShoppingHistory(HttpServletRequest request, HttpServletResponse response) {
System.out.println("showShoppingHistory");
String[] shoppingNames = {"西游记", "红楼梦", "水浒传", "三国演义"};
//获取所有的商品浏览记录(cookie(name=history))
Cookie historyCookie = null;
Cookie[] cookies = request.getCookies();
if (null != cookies && 0 != cookies.length) {
for (Cookie cookie : cookies) {
if ("history".equals(cookie.getName())) {
historyCookie = cookie;
}
}
}
List<String> list = new ArrayList<>();
if (null == historyCookie) {
//没有浏览记录
} else {
//有浏览记录 : 0-1-2-3
String historyStr = historyCookie.getValue();
String[] historyIndexs = historyStr.split("-");
for (String historyIndex : historyIndexs) {
String shoppingName = shoppingNames[Integer.parseInt(historyIndex)];
list.add(shoppingName);
}
}
request.setAttribute("list", list);
try {
processTemplate("shopping_history", request, response);
} catch (IOException e) {
e.printStackTrace();
}
}
}
④编写shopping_history.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>商品浏览记录</title>
</head>
<body>
<div th:if="${list == null || #lists.size(list) == 0}">
没有商品浏览记录
</div>
<div th:if="${!(list == null || #lists.size(list) == 0)}">
<ul>
<li th:each="history : ${list}" th:text="${history}">
</li>
</ul>
</div>
</body>
</html>
CookieUtils工具类
- 代码实现
public class CookieUtils {
public static Cookie getCookie(Cookie[] cookies, String cookieName) {
if (null == cookies || 0 == cookies.length) {
return null;
}
for (Cookie cookie : cookies) {
if (cookieName.equals(cookie.getName())) {
return cookie;
}
}
return null;
}
}
session介绍
- 概述
- 服务器端会话技术;
- 只不过在浏览器端保存的是一个特殊标识,而共享的数据保存到了服务器端的内存对象中。每 次请求时,浏览器都会将特殊标识携带到服务器端,根据这个标识来找到对应的内存空间, 从而实现共享。
- 是一个域对象
- 域对象
- ServletRequest :当前请求
- HttpSession :当前会话
- ServletContext : 当前项目
session基本使用
代码实现
@WebServlet("/demo08")
public class Demo08Servlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
String msg = "helloworld";
session.setAttribute("msg",msg);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
@WebServlet("/demo09")
public class Demo09Servlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
Object msg = session.getAttribute("msg");
System.out.println("msg = " + msg);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
@WebServlet("/demo10")
public class Demo10Servlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
session.removeAttribute("msg");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
session执行流程
执行流程
- ①浏览器发起第一次请求Demo08Servlet
- 创建了一个session对象(9AA02B1B81450DAEBF01023CAF56DC19)
- 通过响应头Set-Cookie(JSESSIONID=9AA02B1B81450DAEBF01023CAF56DC19)携带到浏览器,并保存
- ②浏览器发起第二次请求Demo09Servlet
- 通过请求头Cookie(JSESSIONID=9AA02B1B81450DAEBF01023CAF56DC19)携带到服务器,
- 服务器根据JSESSIONID在服务器容器中找对应JSESSIONID的session对象
- 如果有,直接使用
- 如果没有,就创建新的session对象
- ③浏览器发起第三次请求Demo10Servlet
- 通过请求头Cookie(JSESSIONID=9AA02B1B81450DAEBF01023CAF56DC19)携带到服务器,
- 服务器根据JSESSIONID在服务器容器中找对应JSESSIONID的session对象
- 如果有,直接使用
- 如果没有,就创建新的session对象
sessoin相关配置
存活时长
<!-- ==================== Default Session Configuration ================= -->
<!-- You can set the default session timeout (in minutes) for all newly -->
<!-- created sessions by modifying the value below. -->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
session默认存活时长为30分钟
@WebServlet("/demo08")
public class Demo08Servlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
System.out.println(session.getId());
session.setMaxInactiveInterval(5);
String msg = "helloworld";
session.setAttribute("msg",msg);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}