web(07)会话-session

一、session简介

1.1 抛砖引玉

  1. 不同的用户登录网站后,不管该用户浏览该网站的哪个页面,都可显示登录人的名字,还可以随时去查看自己的购物车中的商品, 是如何实现的?
  2. 也就是说,一个用户在浏览网站不同页面时,服务器是如何知道是张三在浏览这个页面,还是李四在浏览这个页面?

1.2 解决之道—session 技术

  1. Session 是服务器端技术,服务器在运行时为每一个用户的浏览器创建一个其独享的session 对象/集合
  2. 由于 session 为各个用户浏览器独享,所以用户在访问服务器的不同页面时,可以从各自的 session 中读取/添加数据, 从而完成相应任务

二、session基本原理

2.1 示意图

在这里插入图片描述

  1. 当用户打开浏览器,访问某个网站, 操作 session 时,服务器就会在内存(在服务端)为该浏览器分配一个 session 对象,该 session 对象被这个浏览器独占, 如图

  2. 这个 session 对象也可看做是一个容器/集合,session 对象默认存在时间为 30min(这是在tomcat/conf/web.xml),也可修改

在这里插入图片描述

2.2 session 能干嘛

  1. 网上商城中的购物车

  2. 保存登录用户的信息

  3. 将数据放入到 Session 中,供用户在访问不同页面时,实现跨页面访问数据

  4. 防止用户非法登录到某个页面

2.3 理解 Session

  1. session 存储结构示意图

    在这里插入图片描述

  2. 可以把 session 看作是一容器类似 HashMap,有两列(K-V),每一行就是 session 的一个属性。

  3. 每个属性包含有两个部分,一个是该属性的名字(String),另外一个是它的值(Object)

三、session常用的方法

  1. 创建和获取 Session,API 一样

    HttpSession hs=request.getSession();

  2. 向 session 添加属性

    hs.setAttribute(String name,Object val);

  3. 从 session 得到某个属性

Object obj=hs.getAttribute(String name);

  1. 从 session 删除调某个属性:

    hs.removeAttribute(String name);

  2. isNew(); 判断是不是刚创建出来的 Session

  3. 每个 Session 都有 1 个唯一标识 Id 值。通过 getId() 得到 Session 的会话 id 值

四、session底层机制

4.1 session 底层实现机制图解(重要)

在这里插入图片描述

在这里插入图片描述

4.2 代码实现

  1. 创建session
public class CreateSession extends HttpServlet {
	protected void doPost(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException {
		doGet(request, response);
	}
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
	throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		request.getSession().setAttribute("key1", "key1 的值");
		response.getWriter().write("<h1>向 Session 对象 保存属性 key1</h1>");
	}
}

测试 Session 创建的机制, 抓包分析

在这里插入图片描述

  1. 读取session
public class ReadSession extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //System.out.println("ReadSession 被调用...");
        // 演示读取session
        //1. 获取session, 如果没有sesion, 也会创建
        HttpSession session = request.getSession();
        //输出sessionId
        System.out.println("ReadSession sessionid= " + session.getId());
        //2. 读取属性
        Object email = session.getAttribute("email");
        if (email != null) {
            System.out.println("session属性 email= " + (String) email);
        } else {
            System.out.println("session中没有 email属性 ");
        }
        //给浏览器回复一下
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.println("<h1>读取session成功...</h1>");
        writer.flush();
        writer.close();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

测试 Session 读取的机制, 抓包分析

在这里插入图片描述

五、session生命周期

  1. public void setMaxInactiveInterval(int interval) 设置 Session 的超时时间(以秒为单位),超过指定的时长,Session 就会被销毁。
  2. 值为正数的时候,设定 Session 的超时时长。
  3. 负数表示永不超时
  4. public int getMaxInactiveInterval()获取 Session 的超时时间
  5. public void invalidate() 让当前 Session 会话立即无效
  6. 如果没有调用 setMaxInactiveInterval() 来指定 Session 的生命时长,Tomcat 会以 Session默认时长为准,Session 默认的超时为 30 分钟, 可以在 tomcat 的 web.xml 设置
  7. Session 的生命周期指的是 :客户端/浏览器两次请求最大间隔时长,而不是累积时长。即当客户端访问了自己的 session,session 的生命周期将从 0 开始重新计算。(解读: 指的是同一个会话两次请求之间的间隔时间)
  8. 底层: Tomcat 用一个线程来轮询会话状态,如果某个会话的空闲时间超过设定的最大值,则将该会话销毁
  9. session 是否过期,是由服务器来维护和管理
  10. 如我们调用了 invaliate() 会直接将该 session 删除/销毁
  11. 如果希望删除 session 对象的某个属性, 使用 removeAttribute(“xx”)

六、session经典案例-防止非法进入管理页面

6.1 需求说明

在这里插入图片描述

说明:

  1. 只要密码为 666666, 我们认为就是登录成功
  2. 用户名不限制
  3. 如果验证成功,则进入管理页面 ManageServelt.java ,否则进入 error.html
  4. 如果用户直接访问 ManageServet.java , 重定向到到 login.html

6.2 代码实现

两个html界面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录界面</title>
</head>
<body>
<h1>用户登录界面</h1>
<form action="/cookie/loginCheck" method="post">
    用户名:<input type="text" name="username"><br>
    密码:<input type="password" name="pwd"><br>
    <input type="submit" value="登录">
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录失败</title>
</head>
<body>
<h1>登录失败</h1>
<a href="/cookie/login.html">点击返回登录界面</a>
</body>
</html>

创建LoginCheckServlet:

package com.mzq.sessionhomework; /**
 * @author MengZhiQiang
 * @date 2022/4/11 21:57
 * @version 1.0
 */

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;

public class LoginCheckServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("LoginCheckServlet 被调用");
        String username = request.getParameter("username");
        String pwd = request.getParameter("pwd");
        System.out.println("pwd = "+pwd);
        if ("666666".equals(pwd)){
            HttpSession session = request.getSession();
            session.setAttribute("username",username);
            request.getRequestDispatcher("/manage").forward(request,response);
        }else {
            response.sendRedirect(getServletContext().getContextPath()+"/err.html");
        }
    }

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

创建ManageServlet:

package com.mzq.sessionhomework; /**
 * @author MengZhiQiang
 * @date 2022/4/11 22:05
 * @version 1.0
 */

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;

public class ManageServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("ManageServlet 被调用");
        response.setContentType("text/html;charset=utf-8");
        HttpSession session = request.getSession();
        String  username = (String)session.getAttribute("username");
        if (username==null){
            response.sendRedirect(getServletContext().getContextPath()+"/login.html");
        }
        PrintWriter writer = response.getWriter();
        writer.println("<h1>用户管理界面</h1>\n" +
                "<div>欢迎你 管理员:"+username+"</div>");
        writer.flush();
        writer.close();
    }

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

web.xml映射:

	<servlet>
        <servlet-name>LoginCheckServlet</servlet-name>
        <servlet-class>com.mzq.sessionhomework.LoginCheckServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LoginCheckServlet</servlet-name>
        <url-pattern>/loginCheck</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>ManageServlet</servlet-name>
        <servlet-class>com.mzq.sessionhomework.ManageServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ManageServlet</servlet-name>
        <url-pattern>/manage</url-pattern>
    </servlet-mapping>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值