失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 会话管理:Cookie和Session

会话管理:Cookie和Session

时间:2023-12-25 00:03:45

相关推荐

会话管理:Cookie和Session

会话管理

会话概述:

日常生活中:从拨通电话到挂断电话之间的一连串你问我答的过程就是一个会话

B/S架构中:从浏览器第一次给服务器发送请求时,建立会话,直到有一方断开,会话结束。

一次会话:包含多次请求响应

会话技术:

问题:Http是一个无状态协议,同一个会话的连续两个请求相互独立,彼此并不了解

作用:用于存储浏览器与服务器在请求和响应过程中产生的数据

客户端会话技术:cookie

服务器会话技术:session

Cookie

Cookie概述:

它具有name必须的*single value:单一的值必须的*---------以下都可选的---------------------domain它是指定Cookie的域(范围)path它是指定Cookie的路径maxage它是指定Cookie的最大存活时间*------在可选的里面,这两个是一般的---------commentsversion定位Cookie通过的是domain+path+namedomain:path:name:

cookie的值中,不能有 ; , 这些字符。它不支持。

Cookie作用:在一次会话的多次请求之间共享数据,将数据保存到客户端(浏览器)

例如:JD购物车

Cookie快速入门

设置数据到cookie中

// 1.创建cookie对象,设置数据

Cookie cookie = new Cookie(String name,String value);

// 2.通过response,响应(返回)cookie

response.addCookie(cookie);

从cookie中获取数据

// 1.通过request对象,接收cookie数组

Cookie[] cookies = request.getCookies();

// 2.遍历数组

@WebServlet("/SetServlet")public class SetServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 1.创建cookie对象,设置数据Cookie cookie = new Cookie("name","jack");// 2.通过response,响应(返回)cookieresponse.addCookie(cookie);}}

@WebServlet("/GetServlet")public class GetServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 1.通过request对象,接收cookie数组Cookie[] cookies = request.getCookies();// 2.遍历数组if(cookies!=null){for (Cookie c : cookies) {String name = c.getName();String value = c.getValue();System.out.println(name + " : " + value);}}}}

工作原理

基于HTTP协议:请求头cookie和响应set-cookie

Cookie细节

服务器发送多个Cookie

答案是可以的

// 1. 创建多个cookie对象

Cookie cookie1 = new Cookie(“name”,“lucy”);

Cookie cookie2 = new Cookie(“age”,“18”);

// 2. 通过response响应多个

response.addCookie(cookie1);

response.addCookie(cookie2);

@WebServlet("/MultipleCookie")public class MultipleCookie extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 1. 创建多个cookie对象Cookie cookie1 = new Cookie("name","lucy");Cookie cookie2 = new Cookie("age","18");// 2. 通过response响应多个response.addCookie(cookie1);response.addCookie(cookie2);}}

Cookie在浏览器保存时间

默认情况下

浏览器关闭(会话结束),cookie销毁(内存)

设置cookie的存活时间

cookie.setMaxAge(int second); – 单位是秒

正数:指定存活时间,持久化浏览器的磁盘中,到期后自动销毁

负数:默认浏览器关闭,cookie销毁

零:立即销毁(自杀)

@WebServlet("/MaxAgeCookie")public class MaxAgeCookie extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 1.创建cookie对象Cookie cookie = new Cookie("product", "xiaomi10");// 2.设置cookie存活时间// cookie.setMaxAge(-1); // 默认值,浏览器关闭自动销毁// cookie.setMaxAge(60);// 存活30秒,到期自动销毁cookie.setMaxAge(0); // 立即销毁...//3. response响应cookieresponse.addCookie(cookie);}}

Cookie存储中文

tomcat8之前的版本,不支持中文

URLEncoder 编码

URLDecoder 解码

tomcat8以后的版本,支持中文…

Rfc6265Cookie规范,不允许使用 分号、空格、逗号等一些特殊符号…

@WebServlet("/EncodeCookie")public class EncodeCookie extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String product = "华为荣耀 30X,";product= URLEncoder.encode(product, "UTF-8");// 1.创建cookie对象Cookie cookie = new Cookie("product", product);// 2.response响应cookieresponse.addCookie(cookie);}}

@WebServlet("/GetServlet")public class GetServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 1.通过request对象,接收cookie数组Cookie[] cookies = request.getCookies();// 2.遍历数组if(cookies!=null){for (Cookie c : cookies) {String name = c.getName();String value = c.getValue();// 解码value = URLDecoder.decode(value, "UTF-8");System.out.println(name + " : " + value);}}}}

Cookie共享数据的范围

在一个tomcat服务器中部署多个web项目,那么这些web项目的Cookie能否共享?

默认情况下不可以

默认cookie的携带路径,是当前设置cookie的serlvet父路径。。。。

设置cookie:http://localhost:8080/day11_cookie/EncodeCookie

默认携带路径:http://localhost:8080/day11_cookie

指定cookie的携带路径

cookie.setPath(String path);

举例:

cookie.setPath("/");

/ 相当于 http://localhost:8080/

此cookie携带路径

访问

http://localhost:8080/day11_cookie

http://localhost:8080/day10_response

注意

cookie的携带路径不同,名称可以重复…

练习题

设置cookie

http://localhost:8080/day11_cookie/aa/SetCookie

接收cookie

http://localhost:8080/day11_cookie/bb/GetCookie

默认情况下,是否能获取aa目录下的cookie数据?

答案是不可以…

在当前项目下共享cookie

cookie.setPath("/项目名")

* 课下练习题设置cookiehttp://localhost:8080/day11_cookie/aa/SetCookie接收cookiehttp://localhost:8080/day11_cookie/bb/GetCookie默认情况下,是否能获取aa目录下的cookie数据?答案是不可以....在当前项目下共享cookiecookie.setPath("/项目名")

不同tomcat服务器之间Cookie能否共享 默认情况下不可以多个服务器之间的数据共享cookie,需要在同一个一级域名下

cookie.setDomain(".")

Cookie特点

cookie存储数据都在客户端(浏览器)cookie的存储数据智能是字符串cookie单个大小不能超过4KB同一个域名下cookie数量不能超过50个cookie路径不同,可以重名出现cookie存储的数据不太安全

综合案例

用户上次访问记录

需求:

访问一个Servlet,如果是第一次访问,则提示:您好,欢迎您的到来

如果不是第一次访问,则提示:欢迎回来,您上次访问时间为:XXXX。

代码实现

LastTimeServlet

@WebServlet("/LastTimeServlet")public class LastTimeServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");// 1.接收cookie数组,取出指定名称cookie对象Cookie cookie = CookieUtils.findByName("last_time", request.getCookies());// 2.判断if (cookie == null) {// 不存在response.getWriter().write("<h1>欢迎您,首次访问....</h1>");} else {// 存在String value = cookie.getValue();response.getWriter().write("<h1>欢迎回来,您上次访问时间:" + value + "</h1>");}// 3.创建cookie对象,记录本次访问时间SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日-HH:mm:ss");String currentTime = simpleDateFormat.format(new Date());cookie = new Cookie("last_time", currentTime);// 4.设置cookie存活1年cookie.setMaxAge(60 * 60 * 24 * 365);// 5.response响应cookieresponse.addCookie(cookie);}}

CookieUtils

public class CookieUtils {/*根据指定名称,查找cookie对象*/public static Cookie findByName(String name, Cookie[] cookies) {// 非空判断if (cookies != null && cookies.length > 0) {// 遍历for (Cookie cookie : cookies) {// 判断是否有指定名称的cookieif (name.equals(cookie.getName())) {return cookie;}}}// 没找到返回nullreturn null;}}

JSP初体验

Java服务器端页面(Java Server Pages)简单来说:一个特殊的页面,即可定义html标签,又可以定义java代码作用:简化书写,展示动态页面本质:是servlet

脚本:Jsp通过脚本方式来定义java代码

<% java代码 %> 就相当于servlet中service方法…

内置对象:在Jsp页面中不需要获取和创建,可以直接使用的对象

request

response

out

注意:在jsp响应内容,使用out

<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head><title>demo</title></head><body><h3>我是标题</h3><table border="1" width="200" align="center"><tr><td>我是静态资源...</td></tr></table><%System.out.println("我是jsp哈哈哈...");request.getServletContext();out.write("out输出的hehe");// response.getWriter().write("hehe");%></body></html>

商品浏览记录

需求

做一个商品页面,当我们访问后,在页面上点击查看商品浏览记录后,可以查看到以前浏览过的商品信息

需求分析:

代码实现

goods.html

<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><title>goods</title></head><body><h3>商品列表</h3><a href="/day11_cookie/GoodsInfoServlet?name=小米10">小米10</a> <br><a href="/day11_cookie/GoodsInfoServlet?name=华为P40">华为P40</a> <br><a href="/day11_cookie/GoodsInfoServlet?name=iphoneSE">iphoneSE</a> <br><a href="/day11_cookie/GoodsInfoServlet?name=锤子T2">锤子T2</a> <br></body></html>

GoodsInfoServlet

@WebServlet("/GoodsInfoServlet")public class GoodsInfoServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("utf-8"); // 请求解码response.setContentType("text/html;charset=utf-8"); // 响应编码// 1.获取请求参数 name 小米10String product = request.getParameter("name");// 2.展示当前商品详情response.getWriter().write("您当前浏览的商品为:" + product);// 3.获取指定名称cookie对象Cookie cookie = CookieUtils.findByName("goods_name", request.getCookies());// 4.判断是否存在...if (cookie == null) {// 5.如果不存在,将当前商品设置到cookie对象中...cookie = new Cookie("goods_name", product);} else {// 6.如果有,将浏览记录取出,格式:小米10-华为P40String value = cookie.getValue();// 7.判断当前商品是否在此cookie中List<String> list = Arrays.asList(value.split("-"));// 8.如果不包含,追加if (!list.contains(product)) {value = value + "-" + product; // 格式:小米10-华为P40}// 9.将value,重置到cookie中cookie = new Cookie("goods_name", value);}// 10.通过response响应到浏览器// 设置存活时间 为1年cookie.setMaxAge(60 * 60 * 24 * 365);response.addCookie(cookie);// 11.制作a标签,实现记录浏览商品功能response.getWriter().write("<br><a href='/day11_cookie/goods.html'>继续浏览</a>");// 12.制作a标签,实现查看浏览记录功能response.getWriter().write("<br><a href='/day11_cookie/history.jsp'>浏览记录</a>");}}

history.jsp

<%@ page import="cn.itcast.f_lasttime.CookieUtils" %><%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head><title>history</title></head><body><%// java的代码...// 1.获取指定名称cookie对象Cookie cookie = CookieUtils.findByName("goods_name", request.getCookies());// 2.判断是否存在浏览记录if(cookie == null){// 没有提示out.write("暂无浏览记录....");}else{// 有的话,遍历显示out.write("浏览记录如下:<br>");String value = cookie.getValue(); // 格式:小米10-华为P40for (String product : value.split("-")) {out.write(product+"<br>");}}%></body></html>

Session

Session概述

先来看看使用Cookie的问题(缺点):

1. 最多存储4KB字符串

2. 存储数据不太安全(由于Cookie是在客户端,很多操作用户都能自己去修改获取查看)

session作用:在一次会话的多次请求之间共享数据,将数据保存到服务器端

Session快速入门

HttpSession也是一个域对象

API 存储数据

void setAttribute(String name,Object value)获取数据

Object getAttribute(String name)删除数据

void removeAttribute(String name)

步骤分析:

将数据存储到session中

// 1.通过rquest对象,获取session对象

HttpSession session = request.getSession();

// 2.操作session的API,存储数据

session.setAttribute(“username”,“哈哈,呵呵”);

从session中获取数据

// 1.通过rquest对象,获取session对象

HttpSession session = request.getSession();

// 2.操作session的API,获取数据

session.getAttribute(“username”);

@WebServlet("/SetSession")public class SetSession extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 1.通过rquest对象,获取session对象HttpSession session = request.getSession();// 2.操作session的API,存储数据session.setAttribute("username", "哈哈,呵呵");}}

@WebServlet("/GetSession")public class GetSession extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 1.通过rquest对象,获取session对象HttpSession session = request.getSession();// 2.操作session的API,获取数据String username = (String) session.getAttribute("username");System.out.println("GetSession获取:" + username);}}

工作原理:

Session基于Cookie技术实现

Session细节

客户端关闭,服务器不关闭

两次获取的Session数据是否相同?

默认情况下,浏览器关闭,再次打开二次获取的session不一样

基于cookie实现(浏览器关闭,cookie销毁)

设置cookie的存活时间(JESSIONID)

这里我们代替服务器,做一个小操作,覆盖这个JSESSIONID,指定持久化时间

客户端不关闭,服务器关闭

两次获取的Session数据是否相同?

当服务器正常关闭,重启后,二次获取的session数据一样

tomcat这哥们实现以下二个功能

钝化(序列化)

当服务器正常关闭时,session中的数据,会序列化到磁盘

活化(反序列化)

当服务器开启后,从磁盘文件中,反序列化到内存中

我们使用的idea工具有坑…

支持钝化

我们可以强制设置idea重启时不清除session会话

生命周期

何时创建

用户第一次调用request.getSession()方法时,创建何时销毁

服务器非正常关闭

非活跃状态30分钟后

tomcat进行配置 /tocmat安装目录/conf/web.xml

session.invalidate(); 自杀作用范围

一次会话中,多次请求之间

注意:每一个浏览器跟服务器都是独立的会话…

URL重写

Session基于Cookie技术实现;浏览器的Cookie是可以禁用的,一旦禁用后Session就会出现问题。

开发中,一般我们是不关注用户的cookie是否禁用的,若用户禁用了cookie,智能用别的网站了。

如果真想处理用户端的cookie禁用,我们可以使用url重写技术:

@WebServlet("/SessionDemo2")public class SessionDemo2 extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 获取session对象HttpSession session = request.getSession();// 向session中存数据session.setAttribute("username", "哈哈,即使浏览器禁用了cookie,也不影响我使用");// 定义urlString url = "/day12_session/GetSession";// 重写url,拼接JSESSIONIDurl = response.encodeURL(url); // /day12_session/GetSession?JSESSIONID=xxsdfasdfSystem.out.println(url);response.setContentType("text/html;charset=utf-8");response.getWriter().write("<a href='" + url + "'>跳转到获取session内容</a>");}}

Session特点:

session存储数据在服务器中session存储类型任意(Object)session存储大小和数量没有限制(相对于内存)session存储相对安全

cookie和Session的选择

cookie将数据保存在浏览器端,数据相对不安全.建议敏感的数据不要放在cookie中,而且数据大小是有限制的 成本低,对服务器要求不高 session将数据保存在服务器端,数据相对安全.数据的大小要比cookie中数据灵活很多 成本较高,对服务器压力较大

综合案例:

商品购物车:

需求:

有一个商品页面,可以点击超链接将商品添加到购物车,还有一个超链接,点击它可以查看购物车中的商品信息

代码实现:

goods.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head><title>goods.jsp</title></head><body><h3>商品列表</h3><a href="/day12_session/AddCartServlet?name=电视机">电视机,加入购物车</a><br><a href="/day12_session/AddCartServlet?name=冰箱">冰箱,加入购物车</a><br><a href="/day12_session/AddCartServlet?name=洗衣机">洗衣机,加入购物车</a><br><a href="/day12_session/AddCartServlet?name=电脑">电脑,加入购物车</a><br></body></html>

AddCartServlet

@WebServlet("/AddCartServlet")public class AddCartServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("utf-8"); // 请求解码response.setContentType("text/html;charset=utf-8");// 响应编码// 1.获取请求参数String product = request.getParameter("name");// 2.返回结果response.getWriter().write(product + ",商品已成功加入购物车 <br>");// 3.从session中获取购物车Map<String, Integer> cart = (Map<String, Integer>) request.getSession().getAttribute("cart");// 4.判断购物车是否为空if (cart == null) {cart = new HashMap<>();}// 5.判断购物车中是否包含本次添加的商品if (cart.containsKey(product)) {// 6.存在,数量+1Integer oldCount = cart.get(product); // 之前数量cart.put(product, oldCount + 1);// 数量加1} else {// 7.不存在,直接添加商品,数量为1cart.put(product, 1);}// 8.重新将购物车,写入到session中request.getSession().setAttribute("cart", cart);// 9.继续浏览response.getWriter().write("<a href='/day12_session/goods.jsp'>继续浏览</a><br>");// 10.查看购物车response.getWriter().write("<a href='/day12_session/cart.jsp'>查看购物车</a><br>");}}

cart.jsp

<%@ page import="java.util.Map" %><%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head><title>cart</title></head><body><h3>购物车页面</h3><table border="1" width="200px" align="center"><tr><th>商品</th><th>数量</th></tr><%// 1.从session中获取购物车Map<String,Integer> cart = (Map<String, Integer>) request.getSession().getAttribute("cart");// 2.判断是否为空if(cart == null){out.write("购物车内暂时没有商品<br>");}else{for (String s : cart.keySet()) {out.write("<tr><td>"+s+"</td><td>"+cart.get(s)+"</td></tr>");}}%></table></body></html>

用户登录(验证码)

需求:

用户访问带有验证码的登陆页面,输入用户名,密码以及验证码实现登录功能

代码实现:

创建web项目导入验证码Servletlogin.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head><title>login.jsp</title></head><body><h3>用户登录</h3><form action="/day12_login/LoginServlet" method="post">用户:<input type="text" name="username"> <br>密码:<input type="password" name="password"><br>验证码:<input type="text" name="checkcode"> <img src="/day12_login/CheckcodeServlet" alt=""><br><input type="submit" value="登录"><span style="color:red"><%String error = (String) request.getAttribute("error");if (error != null) {out.write(error);// 输出提示信息}%></span></form></body></html>

LoginServlet

@WebServlet("/LoginServlet")public class LoginServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}// 课下作业,实现非空判断...protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("utf-8");response.setContentType("text/html;charset=utf-8");// 1.获取用户输入的验证码String checkcode = request.getParameter("checkcode");// 2.获取session中验证码String codeSession = (String) request.getSession().getAttribute("code_session");// 3.校验是否匹配if (!checkcode.equalsIgnoreCase(codeSession)) {// 验证码不配,友情提示...request.setAttribute("error", "验证码输入错误...");// 转发到login.jsprequest.getRequestDispatcher("/login.jsp").forward(request, response);// 代码不在往下执行....return;}// 4.获取用户输入的用户名和密码String username = request.getParameter("username");String password = request.getParameter("password");// 5.判断用户名密码不正确if (!("jack".equals(username) && "123".equals(password))) {// 友情提示request.setAttribute("error", "用户名或密码错误...");// 转发到login.jsprequest.getRequestDispatcher("/login.jsp").forward(request, response);// 代码不在往下执行....return;}// 6. 将用户名存入到session中request.getSession().setAttribute("username", username);// 7.重定向到success.jspresponse.sendRedirect(request.getContextPath() + "/success.jsp");}}

success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head><title>success</title></head><body><h3><%// 获取用户信息String username = (String) request.getSession().getAttribute("username");if (username != null) {out.write("用户您好,登录成功:"+username);}%></h3></body></html>

如果觉得《会话管理:Cookie和Session》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。