JavaWeb学习笔记-11状态管理
Posted Moon&&Dragon
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaWeb学习笔记-11状态管理相关的知识,希望对你有一定的参考价值。
状态管理
概念:
- 无状态: http协议就是无状态的,b/s架构是一次请求响应,完毕后就和服务器失去关系,下一次再重新建立,实际上 真实的业务场景不是这样的!登陆、请求、做一系列操作,都应该当做一个整体来看待,这一个 整体的数据交互过程,就可以称之为状态管理
- 每一次请求响应之间是不能建立关联的
比如理发店:
- 去剪头发,理发店会发送优惠卷,下一次再去,理发店不记得你,但是看到优惠卷就会给你优惠,这张优惠卷就像是cookie
- 还是去剪头发,在理发店开了会员,登记你的手机号,下一次再去,你什么也不用拿,报手机号,理发店就知道你了,这就像是session
1、cookie
- cookie—“小饼干”,浏览器想给web服务器发送请求,服务器会将 少量的数据 以cookie消息头(优惠卷)的方式发送给浏览器,这个消息头会被保存在浏览器
- 当浏览器再次访问服务器的时候(拿着优惠卷去),会将这些 数据以cookie消息头的方式发送给服务器
- cookie一般会保存在 内存 或者 硬盘
- cookie的名称是无法识别中文 的,value一般最好使用中文
- 对于中文名称 可以使用urlencode进行手动编码,如果添加时使用的手动编码,获取是 需要手动解码
添加cookie: 通过响应添加
@WebServlet("/addCookie") public class AddCookieServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 设置响应类型 resp.setContentType("text/html;charset=utf-8"); // 新建一个cookie(key,value) // 对于中文可以使用urlencode进行收到编码 String name = URLEncoder.encode("晓龙", "utf-8"); Cookie c1 = new Cookie(name, "晓龙_云音乐"); Cookie c2 = new Cookie("yy_cloudMusic", "月月_云音乐"); // 把cookie给浏览器 resp.addCookie(c1); resp.addCookie(c2); } }
获取cookie: 通过请求获取
@WebServlet("/findCookie") public class FindCookieServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 设置请求编码 req.setCharacterEncoding("utf-8"); // 设置响应类型 resp.setContentType("text/html;charset=utf-8"); // 得到cookie(验证) Cookie[] cookies = req.getCookies(); // 循环得到所有的cookie for (Cookie c:cookies) { // 如果前面的是中文名称,这里需要手动解码 // 得到cookie消息头的key System.out.println(URLDecoder.decode(c.getName(),"utf-8")); // 得到cookie消息头的value System.out.println(c.getValue()); } PrintWriter writer = resp.getWriter(); writer.println(cookies); } }
设置cookie存活时间(秒数):
- > 0,保存到硬盘上的
- = 0,删除cookie
- < 0,保存在内存中
c1.setMaxAge(0); c1.setMaxAge(-1); c1.setMaxAge(1);
cookie的一些注意点:
- cookie是可以禁止的
- cookie的大小是有限制的(4kb)
- cooike的数量也有限制(300个)
- cookie由于有中文,一定要注意编码问题
- cookie是不安全的
2、cookie案例
案例–勾选记住密码
思路:
- 登陆
- 登陆成功,添加cookie,存到本地
- 下一次再访问login.html,在初始化页面获取cookie
- 解析cookie的name和value
- 复制给对应的文本框和密码框
登陆servlet:
@WebServlet("/login") public class LoginController extends HttpServlet { private LoginDao loginDao = LoginDaoImpl.getInstance(); @Override protected void service(HttpServletRequest res, HttpServletResponse resp) throws ServletException, IOException { // 设置编码 res.setCharacterEncoding("utf-8"); resp.setContentType("text/html;charset=utf-8"); // 获取前端传入参数 String username = res.getParameter("username"); String password = res.getParameter("password"); // 获取是否勾选记住密码 String remember = res.getParameter("rememberPwd"); // 在dao层进行查询用户 UserInfo user = loginDao.getLogin(username, password); // 判断查询 if (user != null) { // 如果选选择了记住密码,添加cookie if ("on".equals(remember)) { resp.addCookie(new Cookie("username", username)); resp.addCookie(new Cookie("password", password)); resp.addCookie(new Cookie("rememberPwd", remember)); } // 重定向 res.getSession().setAttribute("user", user); resp.sendRedirect("main.jsp"); } else { res.setAttribute("msg", "用户名或密码错误!"); res.getRequestDispatcher("login.jsp").forward(res, resp); } } }
前端部分实现(JS):
let moon = { cookies: '', /* 通过名字获取cookie的value */ getCookieByName: function (name) { for (let i = 0; i < this.cookies.length; i++) { let cookie = this.cookies[i].split('='); if (name === cookie[0].trim()) { return cookie[1].trim(); } } } }; /* 在页面初始化完成后检查浏览器cookie,如果有则填充 */ $(document).ready(function () { // 获取cookie moon.cookies = document.cookie.split(";"); // 通过名字获取对应的cookie let username = moon.getCookieByName("username"); let password = moon.getCookieByName("password"); let rememberPwd = moon.getCookieByName("rememberPwd"); // 判断 if (rememberPwd === 'on') { // 将cookie获得的参数添加到表单 $('#username').attr('value', username); $('#password').attr('value', password); $('#rememberPwd').attr('checked', true); } })
3、session
- 浏览器在访问服务器的时候,服务器会创建一个session的对象,当前会话会有唯一的session的id,服务器会将sessionId会以cookie消息头的方式发给浏览器,下一次浏览器再发起请求的时候,就可以比对这个id,通过这种方式就可以管理浏览器和服务器之间的信息交互,这就是状态管理
- 当浏览器关闭,会话就结束了
请求、会话、上下文的区别:
- 三者都可以保存对象,传递对象,setAttribute() getAttribute()
- Request:只能通过转发将数据发送给下一个servlet,因为他们共用同一个request
- 上下文对象 只要服务器不关闭,对象就一直存在
- session(会话)包含很多次操作,当浏览器关闭以后,会话丢失,或者**手动销毁会话**
- 不同浏览器之间的 session不是同一个
- 不同浏览器之间 上下文对象是同一个,数据可以共享
获取session
HttpSession session = req.getSession();
获取session的id
session.getId();
绑定/获取数据
session.setAttribute(String key,Object value); session.getAttribute("key"); session.removeAttribute("key");
销毁/清空session
session.invalidate();
设置session的存活时间
session.setMaxInactiveInterval(秒);
以上是关于JavaWeb学习笔记-11状态管理的主要内容,如果未能解决你的问题,请参考以下文章