Java研学-Cookie与Session

2024-01-07 19:35:16

一 会话跟踪

1 HTTP 无状态

??HTTP 协议是无状态的,一问一答没有记忆,无法确定发出请求的用户身份。即各个请求的请求对象所包含的信息并不相同,一个会话中的多个请求之间无法共享数据,此时可以使用会话跟踪技术

2 会话跟踪技术

??Cookie 客户端会话跟踪技术
??Session 服务端会话跟踪技术(HttpSession)

3 案例

① 创建web项目,添加对应jar包(JSTL)
② login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录</title>
</head>
<body>
<form action="/http/login" method="post">
    <p>账号:<input type="text" name="username"></p>
    <p>密码:<input type="password" name="password"></p>
    <p><input type="submit" value="登录"></p>
</form>
</body>
</html>

③ LoginServlet.java

package http;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/http/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req,
                           HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if("admin".equals(username)&&"123".equals(password)){//登录成功
            req.setAttribute("username",username);
            req.getRequestDispatcher("/index.jsp").forward(req,resp);
        }
    }
}

④ index.jsp

<%--新建index.jsp,显示当前登录的用户名及提供点击查看收件箱--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
  <title>主页</title>
</head>
<body>
欢迎:${username} <br/>
<a href="/http/list">收件箱</a>
</body>
</html>

⑤ ListServlet.java

@WebServlet("/http/list")
public class ListServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        req.setAttribute("username",username);
        /*查询邮件列表信息*/
        List<String> list=new ArrayList<>();
        list.add("邮件一");
        list.add("邮件二");
        list.add("邮件三");
       req.setAttribute("list",list);
       req.getRequestDispatcher("/list.jsp").forward(req,resp);
    }
}

⑥ list.jsp

<%--显示当前用户名及其邮件,提供查询邮件内容--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
   <title>邮件列表</title>
</head>
<body>
欢迎:${username} <br/>
<c:forEach items="${list}" var="email">
   <a href="/http/content">${email}</a> <br/>
</c:forEach>
</body>
</html>

⑦ ContentServlet.java

@WebServlet("/http/content")
public class ContentServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        req.setAttribute("username",username);
        //跳转到详情页
        req.getRequestDispatcher("/content.jsp").forward(req,resp);
    }
}

⑧ content.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>邮件详情页</title>
</head>
<body>
<p>当前登录账号:${username}</p>
<p>这是邮件详情页面</p>
</body>
</html>

二 Cookie

1 概述

??Cookie(客户端技术)程序把各个用户的数据以 cookie 的形式写给用户各自的浏览器。(服务器创建Cookie存到客户端浏览器)当用户使用浏览器访问服务器中的 Web 资源时(再次访问服务器时实现数据共享),就会带着各自的数据到服务器。Web 资源此时处理的是用户各自的数据。
??传递方向:浏览器 -> 服务器(Cookie)-> 浏览器(存入)-> 服务器(获取Cookie 数据)
类似会员卡消费

2 创建 Cookie 对象

Cookie cookie = new Cookie (String name, String value)
属性方法描述
namegetName()共享数据名称(唯一)
valuegetValue()要共享的数据

3 响应 Cookie 给浏览器

// 使用响应对象中的 addCookie(Cookie 对象) 将数据响应给浏览器
resp.addCookie(cookie);

4 服务器端获取 Cookie

// 浏览器发请求时,自动将 Cookie 发送到服务器,服务器程序直接获取即可。
// 数据在请求中,使用请求对象中的 getCookies() 方法获取所有的 Cookie 对象。
Cookie[] cookies = request对象.getCookies();

5 修改 Cookie 数据

// 调用 Cookie 对象的 setValue 方法来覆盖原本的数据,或者重新创建一个同 name 的 Cookie 对象
cookie对象.setValue("大黄");

// 无论哪种方式,修改的都是服务器端内存中的 Cookie 数据,和浏览器中存的 Cookie 没有关系,所以需要重新响应新的 Cookie 到浏览器中进行更新。
resp.addCookie(新的Cookie对象);

6 Cookie 分类

Cookie 总是保存在客户端中,按在客户端中的存储位置,可分为内存 Cookie 和硬盘 Cookie。
内存 Cookie 由浏览器维护,保存在内存中,浏览器关闭后就消失了,其存在时间是短暂的。硬盘
Cookie 保存在硬盘里,有一个过期时间,除非用户手工清理或到了过期时间,硬盘 Cookie 不会被删
除,其存在时间是长期的。所以,按存在时间,可分为非持久 Cookie 和持久 Cookie。
默认情况下 Cookie 属于会话 Cookie,即浏览器关闭则失效,无法使用。

7 设置 Cookie 存活时间

// 在创建 Cookie 对象之后给其设置存活时间
Cookie对象.setMaxAge(int time);
expiry 数值例子含义
大于 0setMaxAge(60)Cookie 存活时间单位为秒
等于 0setMaxAge(0)立即删除当前 Cookie 对象
小于 0setMaxAge(-1)会话 Cookie,浏览器关闭则销毁

8 删除 Cookie

// 设置 Cookie 存活时间的方法即可进行删除,一般是中途删除 Cookie,不是创建后马上删除,所以在设置删除之后需要重新发送给浏览器去更新删除
Cookie对象.setMaxAge(0);
resp.addCookie(Cookie 对象);

9 例子

① login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录</title>
</head>
<body>
<form action="/cookie/login" method="post">
    <p>账号:<input type="text" name="username"></p>
    <p>密码:<input type="password" name="password"></p>
    <p><input type="submit" value="登录"></p>
</form>
</body>
</html>

② LoginServlet

@WebServlet("/cookie/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req,
                           HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if("admin".equals(username)&&"123".equals(password)){//登录成功
            /*登录成功将账号保存到客户端cookie*/
            /*name共享数据名称(唯一)  value要共享的数据*/
            /*new Cookie (String name, String value)*/
            Cookie cookie=new Cookie("username",username);
            Cookie cookie1=new Cookie("username","小黄");
            cookie.setValue("大黄");
           //设置有效时间
            cookie.setMaxAge(120);
            //设置路径
            cookie.setPath("/");
            resp.addCookie(cookie);
            resp.addCookie(cookie1);
            req.setAttribute("username",username);
            req.getRequestDispatcher("/index.jsp").forward(req,resp);
        }
    }
}

③ index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
  <title>主页</title>
</head>
<body>
欢迎:${username} <br/>
<a href="/cookie/list">收件箱</a>
</body>
</html>

④ ListServlet

@WebServlet("/cookie/list")
public class ListServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /*获取cookie信息*/
        Cookie[] cookies = req.getCookies();
        if (cookies!=null){
            for (Cookie cookie : cookies) {
                // 获取账号的cookie
                if (cookie.getName().equals("username")){
                    // 删除cookie
                    cookie.setMaxAge(0);
                    resp.addCookie(cookie);
                  String username = cookie.getValue();
                    // 将账号存储到作用域
                  req.setAttribute("username",username);
                }
            }
        }
        /*查询邮件列表信息*/
        List<String> list = new ArrayList<>();
        list.add("邮件一");
        list.add("邮件二");
        list.add("邮件三");
        req.setAttribute("list", list);
        req.getRequestDispatcher("/list.jsp").forward(req, resp);
    }
}

⑤ list.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
   <title>邮件列表</title>
</head>
<body>
欢迎:${username} <br/>
   <p>当前登录账号:${cookie.username.value}</p>
<c:forEach items="${list}" var="email">
   <a href="/cookie/content">${email}</a> <br/>
</c:forEach>
</body>
</html>

⑥ ContentServlet

@WebServlet("/cookie/content")
public class ContentServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        /*获取cookie信息*/
        Cookie[] cookies = req.getCookies();
        if (cookies!=null){
            for (Cookie cookie : cookies) {
                //获取账号的cookie
                if (cookie.getName().equals("username")){
                    String username = cookie.getValue();
                    //将账号存储到作用域
                    req.setAttribute("username",username);
                }
            }
        }
        //跳转到详情页
        req.getRequestDispatcher("/content.jsp").forward(req,resp);
    }
}

⑦ content.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>邮件详情页</title>
</head>
<body>
<p>当前登录账号:${username}</p>
<p>这是邮件详情页面</p>
</body>
</html>

10 Cookie 的域和路径

① 作用
??使浏览器能够识别 Cookie 发送给对应的服务器,以及识别哪些请求需要携带 Cookie
??默认Cookie 都带了服务器的识别标识以及需要带 Cookie 的资源标识,保护Cookie 中的数据不被带到其他服务器中去。
② 域
??识别服务器,包含 IP:端口或域名:端口,可通过 Cookie 对象的 setDomain 方法设置。默认Cookie 中的域是创建 Cookie 的服务器的域名。域名分类:
一级(主)域名:bilibili.com
多级域名:news.bilibili.com
若想要在相同的主域名下来共享 Cookies 数据,例如,扣扣空间,扣扣音乐共用账号,则只需要
设置 Cookie 的 domain 即可。若主域不同,是无法共享 Cookie 数据。

cookie.setDomain(".bilibili.com");

③ 路径
??识别资源,可通过 Cookie 对象的 setPath 方法设置。默认为创建 Cookie 的资源的路径。
??例:/cookie/login 创建 Cookie,则 path 为 /cookie,则访问 /cookie 开头的资源都会携带该Cookie。
??若想要在访问服务器上的任意资源都带上 Cookie,则只需要在创建 Cookie 之后设置下 path 为 / 即可。

cookie.setPath("/");

④ 小结
若主域不同,不管 path 如何,都无法带上其他主域的 Cookie。
若主域相同,且 path 也为 /,则访问该域下的任意资源都会携带该域的 Cookie。

三 Session

1 概述

??Session 是服务器端技术(服务器创建,存在服务器),服务器运行时可为每个用户的浏览器创建一个其独享的 session 对象
??用户在访问服务器的 Web 资源时,可以把各自的数据放在各自的 session 中,当用户再去访问服务器中的其它 Web 资源时(再次访问服务器时实现数据共享),其它 Web 资源再从用户各自的 session 中取出数据为用户服务。(通过sessionId识别不同的浏览器用户)
原理图
??Session 底层依赖 Cookie 来传递 Session 的 id 值。所以浏览器关闭后 Session 就无法使用了(sessionId 丢失)。服务器会在 30 分钟内清除无操作的 Session 对象。存 sessionId 的 Cookie 为会话Cookie。

2 方法

① 获取session(HttpServletRequest的API)

方法作用
getSession(true)判断是否存在 Session,存在则获取,不存在则创建新 Session 对象返回
getSession(false)判断是否存在 Session,存在则获取,不存在则返回 null
getSession()存在则获取,不存在则创建新 Session 对象返回

② 数据共享(HttpSession的API)

方法作用
setAttribute(String name, Object value)设置属性名和属性值
getAttribute(String name)通过属性名去获取属性值
removeAttribute(String name)从 Session 中移除指定属性名的属性值
invalidate()移除整个 Session 对象,删除所有的属性和属性值

3 例子

① login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录</title>
</head>
<body>
<form action="/session/login" method="post">
    <p>账号:<input type="text" name="username"></p>
    <p>密码:<input type="password" name="password"></p>
    <p><input type="submit" value="登录"></p>
</form>
</body>
</html>

② LoginServlet

@WebServlet("/session/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req,
                           HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        if("admin".equals(username)&&"123".equals(password)){//登录成功
            //账号存储session
            HttpSession session = req.getSession();
            //获取sessionid
            String id = session.getId();
            System.out.println(id);
            //设置超时时间
            session.setMaxInactiveInterval(60*5);
            session.setAttribute("username",username);
            req.getRequestDispatcher("/index.jsp").forward(req,resp);
        }
    }
}

③ index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
  <title>主页</title>
</head>
<body>
欢迎:${username} <br/>
<a href="/session/list">收件箱</a>
</body>
</html>

④ ListServlet

@WebServlet("/session/list")
public class ListServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /*查询邮件列表信息*/
        List<String> list=new ArrayList<>();
        list.add("邮件一");
        list.add("邮件二");
        list.add("邮件三");
       req.setAttribute("list",list);
       // 从Session中获取数据
        System.out.println(req.getSession().getAttribute("username"));
       req.getRequestDispatcher("/list.jsp").forward(req,resp);
    }
}

⑤ list.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
   <title>邮件列表</title>
</head>
<body>
欢迎:${username} <br/>
<p>当前登录账号:${sessionScope.username}</p>
<c:forEach items="${list}" var="email">
   <a href="/session/content">${email}</a> <br/>
</c:forEach>
</body>
</html>

⑥ ContentServlet

@WebServlet("/session/content")
public class ContentServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 从session中获取数据
        System.out.println(req.getSession().getAttribute("username"));
        //跳转到详情页
        req.getRequestDispatcher("/content.jsp").forward(req,resp);
    }
}

⑦ content.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>邮件详情页</title>
</head>
<body>
<p>当前登录账号:${username}</p>
<p>这是邮件详情页面</p>
</body>
</html>

文章来源:https://blog.csdn.net/zhlyxx/article/details/135431471
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。