Cookie&Session

Posted geekfx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cookie&Session相关的知识,希望对你有一定的参考价值。

Cookie

Cookie 翻译过来是饼干的意思
Cookie 是服务器通知客户端保存键值对的一种技术
客户端有了 Cookie 后,每次请求都发送给服务器
每个 Cookie 的大小不能超过 4kb

Cookie cookie = new Cookie("key1", "value1");
resp.addCookie(cookie);
resp.getWriter().write("Cookie 创建成功");

通过浏览器访问此 Servlet 程序:

技术图片

技术图片

技术图片

技术图片

Cookie[] cookies = req.getCookies();
for (Cookie cookie : cookies) {
    resp.getWriter().write(cookie.getName() + " = " + cookie.getValue() + "<br/>");
}

在浏览器中访问此 Servlet 程序:

技术图片

技术图片

技术图片

// 修改 Cookie 方案一:
Cookie cookie = new Cookie("key1", "newValue2");
resp.addCookie(cookie);
resp.getWriter().write("修改 " + cookie.getName() + " = " + cookie.getValue() + " 成功 <br/>");

// 修改 Cookie 方案二:
cookie = CookieUtils.findCookie("key2", req.getCookies());
cookie.setValue("newValue2");
resp.addCookie(cookie);
resp.getWriter().write("修改 " + cookie.getName() + " = " + cookie.getValue() + " 成功 <br/>");

在浏览器中访问此 Servlet 程序:

技术图片

技术图片

Cookie 的生命控制指的是如何管理 Cookie 什么时候被销毁(删除)

void setMaxAge(int expiry)

  • 正数:表示多少秒后销毁
  • 0:表示立即销毁
  • 负数:表示会话结束后销毁(默认值,-1)

技术图片

技术图片

技术图片

关闭浏览器后重新打开:

技术图片

Cookie 的 path 属性可以有效的过滤哪些 Cookie 可以发送给服务器 哪些不发
path 属性是通过请求的地址来进行有效的过滤。

CookieA:path = /工程路径
CookieB:path = /工程路径/geekfx

请求地址如下:

http://ip:port/工程路径/a.html

  • CookieA:发送
  • CookieB:不发送

http://ip:port/工程路径/geekfx/b.html

  • CookieA:发送
  • CookieB:发送
Cookie cookieA = new Cookie("CookieA", "geekfx");
cookieA.setPath(req.getContextPath());
Cookie cookieB = new Cookie("CookieB", "geekfx");
cookieB.setPath(req.getContextPath() + "/geekfx");
resp.addCookie(cookieA);
resp.addCookie(cookieB);

执行 Servlet 程序后:

技术图片

http://ip:port/工程路径 下查看 cookie:

技术图片

将浏览器地址栏地址还为 http://ip:port/工程路径/geekfx/b.html (实际没有此目录和页面):

技术图片

查看 cookie 信息和请求头信息:

技术图片

技术图片

技术图片

<body>
<form action="cookieLoginServlet" method="get">
    用户名:<input type="text" name="username" value="${cookie.username.value}"> <br>
    密码:<input type="password" name="password" value="${cookie.password.value}"> <br>
    <input type="submit">
</form>
</body>
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println("进入 doGet() 方法");
        // 模拟登录 写死了用户名和密码
        if("geekfx".equals(username) && "123".equals(password)) {
            System.out.println("登陆成功");
            Cookie cookie = new Cookie("username", username);
            cookie.setMaxAge(60 * 60 * 24 * 7);
            resp.addCookie(cookie);
            cookie = new Cookie("password", password);
            cookie.setMaxAge(60 * 60 * 24 * 7);
            resp.addCookie(cookie);
        } else {
            System.out.println("登陆失败");
            req.getRequestDispatcher("/login.jsp").forward(req, resp);
        }
    }

在浏览器输入正确的用户名和密码

技术图片

关闭浏览器,再次打开登录页面:

技术图片

Session 会话

Session 就一个接口(HttpSession)
Session 就是会话。它是用来维护一个客户端和服务器之间关联的一种技术
每个客户端都有自己的一个 Session 会话
Session 会话中,我们经常用来保存用户登录之后的信息

创建/获取 Session 对象

HttpSession request.getSession();
第一次调用是创建 Session 会话
之后调用都是获取前面创建好的 Session 会话对象

boolean isNew();
判断当前 Session 会话对象是否是新创建的
返回 true 表示新创建的
返回 false 表示不是新创建的

String getId();
每个会话都有一个唯一标识的 id 号

HttpSession session = req.getSession();
resp.getWriter().write("当前 Session 对象:" + session + "<br/>");
resp.getWriter().write("是否新创建:" + session.isNew() + "<br/>");
resp.getWriter().write("Session id:" + session.getId() + "<br/>");

第一次访问此 Servlet 程序时:

技术图片

在不关闭浏览器的情况下重新访问:

技术图片

Session 域

Session 也是 JSP 四大域对象之一,可以存取数据

// Session 域数据的存储
req.getSession().setAttribute("key1", "value1");
resp.getWriter().write("Session 域数据存放成功");
// Session 域数据读取
String attribute = (String) req.getSession().getAttribute("key1");
resp.getWriter().write("当前 Session 域数据:" + "key1 = " + attribute);

Session 生命周期

  • int getMaxInactiveInterval();
    获取当前 Session 对象的超时时间,单位为秒,默认 30 分钟(Tomcat)
  • void setMaxInactiveInterval(int interval);
    设置当前 Session 对象的超时时间,单位为秒
    正数:Session 对话超时的秒数
    负数:永不超时
  • void invalidate();
    使当前 Session 会话立即无效

为什么说 Session 的默认超时时长是 30 分钟,因为在 IDEA 整合的 Tomcat 服务器中的配置文件,配置了所有 Session 会话的超时时长默认为 30 分钟:

技术图片

如果想修改某个 web 工程下的所有 Session 会话时长默认时长,可以在 web 工程下的 web.xml 配置文件中配置:

技术图片

protected void invalidate(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    HttpSession session = req.getSession();
    session.invalidate();
    resp.getWriter().write("当前 Session 会话已被销毁");
}

protected void setMaxInactiveInterval(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    int interval = CookieUtils.parseInt(req.getParameter("interval"), 3600);
    HttpSession session = req.getSession();
    session.setMaxInactiveInterval(interval);
    resp.getWriter().write("当前 Session 会话超时时长设置为:" + interval + " 秒");
}

protected void defaultLife(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    HttpSession session = req.getSession();
    int maxInactiveInterval = session.getMaxInactiveInterval();
    resp.getWriter().write("当前 Session 会话的超时时长:" + maxInactiveInterval + " 秒");
}

浏览器和 Session 关联

技术图片

在浏览器没有任何 cookie 的情况下访问服务器:

技术图片

技术图片

访问之后,查看浏览器的响应头和 cookie 信息:

技术图片

技术图片

后面再次访问服务器并试图获取 session 对象,浏览器会将 cookie 信息发送给服务器,包括 JSESSIONID 的 cookie 信息:

技术图片

技术图片

以上是关于Cookie&Session的主要内容,如果未能解决你的问题,请参考以下文章

Cookie&Session

会话技术:Cookie && Session

jsp&cookie&session-01

Session&&cookie

Cookie&Session

Cookie&Session