展开
拓展 关闭
订阅号推广码
GitHub
视频
公告栏 关闭

javaweb开发(七):cookie和session

  • cookie简介
# 浏览器发送request请求到服务器,服务器除了返回请求的response之外,还给请求分
配⼀个唯⼀标识ID和response⼀并返回给浏览器
# 服务器在本地创建⼀个map结构,专⻔以key-value存储这个ID标识和浏览器的关系
# 当浏览器的第⼀次请求后已经分配⼀个ID,当第⼆次访问时会⾃动带上这个标识ID,服
务会获取这个标识ID去map⾥⾯找上⼀次request的信息状态且做对应的更新操作 服务
端⽣成这个全局的唯⼀标识,传递给客户端⽤于标记这次请求就是cookie; 服务器创建
的那个map结构就是session
# cookies由服务端⽣成,⽤于标记客户端的唯⼀标识,在每次⽹络请求中,都会被传
送
# session服务端⾃⼰维护的⼀个map数据结构,记录key-Object上下⽂内容状态
核⼼:它⽤于告知服务端两个请求是否来⾃同⼀浏览器,如保持⽤户的登录状态
# Cookie使基于⽆状态的HTTP协议记录稳定的状态信息成为了可能。 浏览器查看多个站
点的cookie
  • cookie的属性
Name : 名称
Value : 值
Domain:表示当前cookie所属于哪个域或⼦域下⾯
Expires/Max-age:表示了cookie的有效期,是⼀个时间,过了这个时间,该cookie就失效了
Path:表示cookie的所属路径。
size: ⼤⼩,多数浏览器都是4000多个字节
http-only: 表示这个cookie不能被客户端使⽤js读取到,是不公开的cookie,(chrome调试器的console中输⼊document.cookie将得不到标记为HttpOnly的字段)
Secure: 标记为 Secure 的Cookie只应通过被HTTPS协议加密过的请求发送给服务端, 从 Chrome 52 和 Firefox 52 开始,不安全的站点(http:)⽆法使⽤Cookie的 Secure标记
SameSite(特有的,可以忽略)

  • cookie缺陷
cookie会被附加在每个HTTP请求中,增加了流量。
在HTTP请求中的cookie是明⽂传递的,所以安全性成问题,除⾮⽤HTTPS
Cookie的⼤⼩有限制,对于复杂的存储需求来说不满⾜
  • 浏览器允许每个域名所包含的cookie数量
多数浏览器允许最多是50个,部分浏览器是30或者20;
满后会有多种剔除策略,⽐如LRU,权重等
  • cookie实战
客户端第1次请求服务端时,服务端会返回cookie和response
客户端将cookie存储起来
客户端第2次及以后每次访问服务端都会带上cookie
  • 获取第1次请求的cookie
@WebServlet("/get_cookie")
public class GetCookieServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Cookie[] cookies = request.getCookies();
        for(Cookie cookie : cookies){
            System.out.println(cookie.getDomain());
            System.out.println(cookie.getName());
            System.out.println(cookie.getValue());
        }
    }

}
  • 测试,控制台清空后访问,访问后返回cookie
http://localhost:8080/get_cookie

# 控制台输出
null
JSESSIONID
FF39D4A8A5EBC89F25969E1BD4FC602A
  • 自定义cookie并返回给前端
@WebServlet("/gene_cookie")
public class GeneCookieServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 创建cookie对象
        Cookie cookie = new Cookie("token","sfwerawefewadaewfafewafa");
        //20秒过期时间,过期后不会自动携带过去
        cookie.setMaxAge(20);
        // 返回时,返回cookie
        response.addCookie(cookie);
        // 转发页面
        request.getRequestDispatcher("/index.jsp").forward(request,response);
    }

}
  • 测试
http://localhost:8080/gene_cookie

  • session简介
# 浏览器第⼀次发送request请求到服务器,服务器除了返回请求的response之外,还给请求
分配⼀个唯⼀标识sessionId和response⼀并返回给浏览器
# 服务器在本地创建⼀个map结构,专⻔以key-value存储这个sessionId和浏览器的关系
# 当浏览器的第⼀次请求后已经分配⼀个sessionId,当第⼆次访问时会⾃动带上这个标识
sessionId
# 服务器通过查找这个sessionId就知道⽤户状态了,并更新sessionId的最后访问时间

注意: Session是有时限性的:⽐如如果30分钟内某个session都没有被更新,服务器就会删
除这个它
  • cookie与session的关系
服务端⽣成这个全局的唯⼀标识,传递给客户端⽤于标记这次请求就是cookie
服务器创建的那个map结构就是session
cookies由服务端⽣成,⽤于标记客户端的唯⼀标识,在每次⽹络请求中,都会被传送。
session服务端⾃⼰维护的⼀个map数据结构,记录key-Object上下⽂内容状态
总⾔之cookie是保存在客户端,session是存在服务器,session依赖于cookie
cookie⾥⾯存储的就是JSESSIONID
  • 拓展
# session是存储在服务端的内存中,在javaweb⾥⾯叫HttpSession也是⼀个作⽤域
# PageContext(⻚⾯)->ServletRequest(请求)->【HttpSession】(会话)->ServletContext(⼀个
应⽤)
# 是可以存储很多key-value的,作⽤域⽐较⼴,所以也不能存储过多内容,因为内存是有限制
的,互联⽹企业使⽤⽐较少,传统IT公司使⽤⽐较多
  • 创建sessionid
# 创建SessionServlet 

@WebServlet("/session")
public class SessionServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 创建session对象
        HttpSession session = request.getSession();
        //获取sessionid,java里面叫jsessionid
        System.out.println("sessionid="+session.getId());
        //创建时间戳,毫秒
        System.out.println("getCreationTime="+session.getCreationTime());
        //是否是初次创建,记得情况浏览器的cookie,验证sessionid
        System.out.println("isNew="+session.isNew());
        //往session存储东西
        session.setAttribute("name","goudan");
    }

}
  • 启动项目测试
  • 清空session
  • 第1次访问,返回sessionid
# 控制台,表示初次创建
sessionid=8BFC3D3140B3539B18DF1348EBC369ED
getCreationTime=1649860447633
isNew=true
  • 第2次访问
# 控制台打印如下,表示不是第一次创建
sessionid=8BFC3D3140B3539B18DF1348EBC369ED
getCreationTime=1649860447633
isNew=false
  • session实现登录
# 编写LoginServlet 
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取参数
        String name = req.getParameter("name");
        String pwd = req.getParameter("pwd");
        // 如果用户名和密码正确,则将用户信息存入session
        if(name.equals("user") && pwd.equals("123")){
            User user = new User();
            user.setId(121);
            user.setName(name);
            user.setHost("xdclass.net");
            req.getSession().setAttribute("loginUser",user);
            // 登录成功后,转发到user.jsp
            req.getRequestDispatcher("/WEB-INF/user.jsp").forward(req,resp);
        }else{
            // 登录失败后,返回错误信息存入领域对象中,并转发到login.jsp
            req.setAttribute("msg","账号密码错误");
            req.getRequestDispatcher("/login.jsp").forward(req,resp);
        }
    }

}


# 编写LogoutServlet 
@WebServlet("/logout_servlet")
public class LogoutServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 退出登录时,销毁session,并转发到login.jsp
        HttpSession session = request.getSession();
        session.invalidate();
        request.getRequestDispatcher("/login.jsp").forward(request,response);
    }

}


# 编写登录成功的页面,user.jsp
<body>
id:${loginUser.id}
<br>
name:${loginUser.name}
<a href="/logout_servlet">退出</a>
</body>


# 编写登录页面,login.jsp
<body>
<form action="<%=request.getContextPath()%>/loginServlet" method="post">
    名称:<input type="text" name="name"/>
    <br/>
    密码:<input type="password" name="pwd"/>
    <input type="submit" value="登录">
    消息提示 ${msg}
</form>
</body>


# web.xml中设置session超时时间
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
  • 启动项目测试

  • 登录成功

  • 退出登录,销毁sessionid,生成新的sessionid

  • 个人理解

# 客户端首次访问服务器时,服务器生成sessionid,将sessionid保存在cookie中发送个客户端;服务端则将sessionid保存在session中,记录了这个请求与服务端的关系
# 客户端再次访问服务端时,就会带上cookie,服务端拿到cookie中的sessionid,与session中id比较,一致则允许访问
# 当服务端的session失效时,则会生成新的sessionid返回给客户端
posted @ 2022-04-13 20:42  DogLeftover  阅读(39)  评论(0编辑  收藏  举报