Java动态修改用户Session实战-动态修改Session实现

锋哥原创的Java动态修改用户Session实战:

Java动态修改用户Session实战课程_哔哩哔哩_bilibiliJava动态修改用户Session实战课程,管理员可以修改任意一个用户的session信息作者:java1234_小锋站点:www.java1234.vip喜欢的朋友点赞+关注B站支持下哈!, 视频播放量 839、弹幕量 1、点赞数 17、投硬币枚数 6、收藏人数 16、转发人数 1, 视频作者 java1234官方, 作者简介 公众号:java1234 微信:java9266,相关视频:2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~,打造前后端分离 权限系统 基于SpringBoot2+SpringSecurity+Vue3.2+Element Plus 视频教程 (火爆连载更新中..),Python爬虫实战-批量爬取下载网易云音乐,PyQt6图书管理系统视频教程 Python桌面开发 Python入门级项目实战 (无废话版) 火爆连载更新中~,Java报表之JFreeChart视频教程,SpringBoot微信小程序电商实战项目课程 Vue3.2 Element Plus后台管理 ( 火爆连载更新中... ),uniapp微信小程序投票系统实战课程 (SpringBoot2+vue3.2+element plus ) ( 火爆连载更新中... ),微信小程序(java后端无废话版)视频教程,实战阿里分布式事务框架Seata视频教程(无废话,通俗易懂版),【免费】springboot+vue在线考试系统 Java毕业设计icon-default.png?t=N7T8https://www.bilibili.com/video/BV1jh411B7Lp/我们来实现下具体代码:

我们定义一个自定义session上下文MySessionContext,里面定义HashMap属性来存储session信息,格式 sessionId :session对象;

package com.java1234.custom;

import javax.servlet.http.HttpSession;
import java.util.HashMap;

/**
 * 自定义session上下文
 * @author java1234_小锋
 * @site www.java1234.com
 * @company 南通小锋网络科技有限公司
 * @create 2021-08-05 10:39
 */
public class MySessionContext {

    private static MySessionContext instance;
    // session map存储session  如果session较多,影响到系统性能的话,可以把用redis,key-value  sessionId->session对象 session对象序列化
    public static HashMap sessionMap;

    private MySessionContext() {
        sessionMap = new HashMap();
    }

    /**
     * 单例
     * @return
     */
    public static MySessionContext getInstance() {
        if (instance == null) {
            instance = new MySessionContext();
        }
        return instance;
    }

    /**
     * 添加session
     * @param session
     */
    public synchronized void addSession(HttpSession session) {
        if (session != null) {
            System.out.println("session添加成功!");
            sessionMap.put(session.getId(), session);
        }
    }

    /**
     * 删除session
     * @param session
     */
    public synchronized void delSession(HttpSession session) {
        if (session != null) {
            System.out.println("session删除成功!");
            sessionMap.remove(session.getId());
        }
    }

    /**
     * 根据sessionId获取session
     * @param sessionID
     * @return
     */
    public synchronized HttpSession getSession(String sessionID) {
        if (sessionID == null) {
            return null;
        }
        return sessionMap.get(sessionID);
    }
}

新建session监听器SessionListener,监听session创建和销毁;

session创建的时候,把session信息存储到自定义session上下文;session销毁时,自定义session上下文中也删除掉该session;

注意,要加@WebListener注解

package com.java1234.listener;

import com.java1234.custom.MySessionContext;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

/**
 * session监听器
 * @author java1234_小锋
 * @site www.java1234.com
 * @company 南通小锋网络科技有限公司
 * @create 2021-08-05 10:43
 */
@WebListener
public class SessionListener implements HttpSessionListener {

    // 获取自定义session上下文实例
    private MySessionContext msc = MySessionContext.getInstance();

    /**
     * session创建事件
     * @param se
     */
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        System.out.println("session创建");
        HttpSession session = se.getSession();
        msc.addSession(session);  // 添加当前session到自定义session上下文
    }

    /**
     * session销毁事件
     * @param se
     */
    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        System.out.println("session销毁");
        HttpSession session = se.getSession();
        //todo 要从数据库或者redis缓存把指定sessionId的用户session信息删除
        msc.delSession(session);  // 从自定义session上下文里删除当前session
    }
}

在springboot项目中,要使得监听器有效,我们启动类要加@ServletComponentScan注解

@ServletComponentScan,自动扫描带有(@WebServlet, @WebFilter, and @WebListener)注解的类,完成注册

Java动态修改用户Session实战-动态修改Session实现_第1张图片

到了这里,我们来测试下监听器是否有效;

启动项目,浏览器地址栏输入:http://localhost/user/login

Java动态修改用户Session实战-动态修改Session实现_第2张图片

说明监听器触发成功,session添加成功!

session的销毁方法触发,有以下三种方式;

1、超时(一般服务器设置超时时间为30分钟)服务器会销毁session;

2、点击控制台的红色按钮异常关闭服务器要销毁session

3、手动调用session的invalidate方法session.invalidate();

为了演示,我把session有效期设置成30秒;

server:
  port: 80
  servlet:
    context-path: /
    session:
      timeout: 30s

我们执行模拟登录30秒后,只要不继续请求操作,30秒后,触发session销毁事件,session删除;

修改UserController,通过session获取servletContext上下文,存储用户session信息,格式 { userId : sessionId }

/**
     * 模拟用户登录
     * @return
     */
    @RequestMapping("/login")
    public String login(HttpSession session){
        User uesr=new User(1,"java1234","123456");
        session.setAttribute("currentUser",uesr);
        System.out.println(session.getId());
        ServletContext servletContext = session.getServletContext();
        // 模拟存储用户session信息到数据库 用application模拟
        servletContext.setAttribute(String.valueOf(uesr.getId()),session.getId()); // key-value 用户id-sessionId
        return "success";
    }

创建ManagerController测试:

package com.java1234.controller;

import com.java1234.custom.MySessionContext;
import com.java1234.entity.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import java.util.HashMap;


/**
 * 管理员Controller控制器
 * @author java1234_小锋
 * @site www.java1234.com
 * @company 南通小锋网络科技有限公司
 * @create 2021-08-07 23:05
 */
@RequestMapping("/manager")
@RestController
public class ManagerController {

    /**
     * 模拟用户登录
     * @return
     */
    @RequestMapping("/modifySession")
    public String modifySession(HttpSession session){
        ServletContext servletContext = session.getServletContext();
        String userId="1"; // 修改userId=1的用户
        String sessionId = (String)servletContext.getAttribute(userId);  // 从servletContext上下文 根据userId获取sessionId
        System.out.println("sessionId:"+sessionId);
        HashMap sessionMap = MySessionContext.sessionMap; // 获取sessionMap
        HttpSession currentSession = sessionMap.get(sessionId); // 根据sessionId获取用户session
        User user = (User)currentSession.getAttribute("currentUser"); // 根据session得到用户信息
        user.setLevel("vip"); // 修改内容
        return "success";
    }
}

浏览器地址栏:http://localhost/user/login 模拟登录

Java动态修改用户Session实战-动态修改Session实现_第3张图片

浏览器地址栏:http://localhost/user/getUserInfo 获取用户信息

Java动态修改用户Session实战-动态修改Session实现_第4张图片

我们另外开一个浏览器地址栏:http://localhost/manager/modifySession 模拟管理员修改session

Java动态修改用户Session实战-动态修改Session实现_第5张图片

然后刷新getUserInfo;

Java动态修改用户Session实战-动态修改Session实现_第6张图片

我们发现session会话信息变了。测试成功!

在高并发下,同一时刻登录用户会很多,如果把session都放内存,会影响性能,甚至内存溢出;所以session可以存储到redis;

另外如下图的两个存储介质,也要存储到redis,以达到最佳性能;

Java动态修改用户Session实战-动态修改Session实现_第7张图片

你可能感兴趣的:(java,java,服务器,开发语言,Session,修改Session)