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

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。

img

小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>
    

自言自语

简单的一天。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值