zl程序教程

您现在的位置是:首页 >  后端

当前栏目

JavaWeb 入门篇 (5) Cookie 和 Session 详解

Cookie 详解 session javaweb 入门篇
2023-06-13 09:14:16 时间

Cookie 和 Session 详解

一、会话的概念

会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。   有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学曾经来过,这称之为有状态会话。

二、会话过程中要解决的一些问题?

每个用户在使用浏览器与服务器进行会话的过程中,不可避免各自会产生一些数据,程序要想办法为每个用户保存这些数据。

三、保存会话数据的两种技术

3.1、Cookie

Cookie的由来

  • 首先我们需要介绍一下,在Web开发过程中为什么会引入Cookie。我们知道Http协议是一种无状态协议, Web服务器本身不能识别出哪些请求是同一个浏览器发出的,浏览器的每一次请求都是完全孤立的。 即便在Http1.1支持了持续连接,但当用户有一段时间没有提交请求时,连接也会自动关闭。这时,作为Web服务器, 必须采用一种机制来唯一标识一个用户,同时记录该用户的状态。于是就引入了第一种机制:Cookie机制。
  • Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。
  • Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的一种方式。
  • Cookie保存在客户端,只能保存字符串对象,不能保存对象类型,需要客户端浏览器的支持:客户端可以不支持,因为浏览器用户可能会禁用Cookie。

Cookie的定义即基本介绍

Cookie是在浏览器访问WEB服务器的某个资源时, 由WEB服务器在HTTP响应消息头中附带传送给浏览器的一个小文本文件。

  1. 一旦WEB浏览器保存了某个Cookie, 那么它在以后每次访问该WEB服务器时, 都会在HTTP请求头中将这个Cookie回传给WEB服务器。
  2. 一个Cookie只能标识一种信息, 它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)。
  3. 一个WEB站点可以给一个WEB浏览器发送多个Cookie, 一个WEB浏览器也可以存储多个WEB站点提供的Cookie。
  4. 浏览器一般只允许存放300个Cookie, 每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。

Cookie的原理

底层的实现原理: WEB服务器通过在HTTP响应消息中增加Set-Cookie响应头字段将Cookie信息发送给浏览器, 浏览器则通过在HTTP请求消息中增加Cookie请求头字段将Cookie回传给WEB服务器。

Cookie的操作

创建、添加、设置时间、删除

public Cookie(String name, String value) ;  // 创建cookie
public void setComment(String purpose); // 设置cookie的描述
public void setMaxAge(int expiry)  // 设置 cookie的时间 单位为秒
public String getName() // 获得存的cookie的名字 
public String getValue()  // 获的cookie的值
// 删除的话 是设置时间为 0

3.2、Session

概述

  • Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务。
  • 之前我们介绍的cookie是把用户的身份信息存在了客户端,而session说白了就是把用户的信息保存在了服务端。由于session是保存在了服务端,所以当用户关闭浏览器时session并不会消失。一般session保存在服务器的内存中当然也可以持久化到硬盘或者数据库中。session的默认过期时间是30分钟,过期的session会被服务器自动的销毁。注意如果大量的创建session可能导致服务器的内存溢出。

一、session的创建流程

当客户端浏览器访问服务器时,服务器会先检查该请求是否携带一个叫JESESSIONID的cookie,如果存在会根据JESESSIONID的cookie值获取存放在服务器端的session值;如果不存在会新建一个session然后把sessionId写到cookei中返回给浏览器,下次浏览器访问时就会携带这个cookie。

小demo

测试1 第一次登录不展示名字 第二次会展示存进去的值。

public class TestSessionServlet extends HttpServlet{
    private static final long serialVersionUID = 1L;

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

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession session = request.getSession();
        response.setCharacterEncoding("utf-8");
        response.setHeader("content-type","text/html;charset=UTF-8");
        PrintWriter writer =  response.getWriter();
        String loginName = (String) session.getAttribute("loginName");
        String sessionId = session.getId();
        if(StringUtils.isEmpty(loginName)){
            session.setAttribute("loginName","张三");
            writer.println("session中没有值!");
        }else{
            writer.println("loginName="+loginName);
        }
        writer.println("sessionId="+sessionId);
        writer.close();
        
    }
}

JavaWeb 中 Session 模拟登录、拦截

表单页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>login</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/sessionLogin" method="post">
    用户名:<input name="username" type="text">
    密码:<input name="password" type="password">
    <input type="submit" value="Login">
</form>
</body>
</html>

里面用到的User类

/**
 * @author crush
 */
public class User {
    private String username;
    private String password;

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

处理登录的Servlet

/**
 * @author crush
 * 实现自动登录
 */
@WebServlet("/sessionLogin")
public class Login extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 开启session
        HttpSession session = req.getSession();
        // 获取登录的参数
        String username = req.getParameter("username");
        String password=req.getParameter("password");
        // 设置字符编码
        resp.setContentType("text/html;charset=utf-8");

        PrintWriter writer = resp.getWriter();
        // 判断用户名和密码是否正确
        if(username.equals("admin")&&password.equals("123456")){
            // 存session
            session.setAttribute("user",new User(username,password));
            session.setMaxInactiveInterval(200);
            writer.print("恭喜你登录成功!!!");
        }
        else{
            System.out.println("账号或密码错误");
            resp.sendRedirect("/login.jsp");
        }
    }
}

mian2请求 测试是否登录的请求

/** 
 * @author crush
 */
@WebServlet("/main2")
public class Main extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();

        User user =(User) session.getAttribute("user");

        // 设置字符编码
        resp.setContentType("text/html;charset=utf-8");

        if(user==null){
            // 没有登录会转向登录页面
            resp.sendRedirect("/login.jsp");
        }
        else{
            req.setAttribute("success","恭喜你做出了登录的小Demo!!!");
            req.getRequestDispatcher("/hello.jsp").forward(req,resp);
        }
    }

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

Hello.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>hello</title>
</head>
<body>
${success}
<br>
</body>
</html>

自言自语

简单的一天。