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状态管理的主要内容,如果未能解决你的问题,请参考以下文章

JAVAWEB学习笔记16

JavaWeb学习笔记11--JSTL标签库

JavaWeb学习笔记五 会话技术Cookie&Session

Javaweb学习笔记8(Response对象)

JAVAWEB学习笔记16_session&cookie

JAVAWEB学习笔记23