自己实现httpsession

package com.kongjs.emo.web.session;import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionContext;
import java.util.*;
// 实现类
public class Session implements HttpSession {private String id;private final long creationTime;private int maxInactiveInterval;private long lastAccessedTime;private final ServletContext servletContext;private Map<String, Object> attributes;private boolean isNew;private long responseEndTime;public Session(ServletContext servletContext, String id) {long now = System.currentTimeMillis();this.id = id;this.creationTime = now;this.maxInactiveInterval = servletContext.getSessionTimeout() * 60;this.lastAccessedTime = now;this.servletContext = servletContext;this.attributes = new HashMap<>();this.isNew = true;this.responseEndTime = now;}@Overridepublic long getCreationTime() {return this.creationTime;}@Overridepublic String getId() {return this.id;}@Overridepublic long getLastAccessedTime() {return this.lastAccessedTime;}@Overridepublic ServletContext getServletContext() {return this.servletContext;}@Overridepublic void setMaxInactiveInterval(int i) {this.maxInactiveInterval = i;}@Overridepublic int getMaxInactiveInterval() {return this.maxInactiveInterval;}@SuppressWarnings(value = "deprecated")@Overridepublic HttpSessionContext getSessionContext() {throw new RuntimeException("不支持");}@Overridepublic Object getAttribute(String name) {return this.attributes.get(name);}@SuppressWarnings(value = "deprecated")@Overridepublic Object getValue(String name) {return this.attributes.get(null);}@Overridepublic Enumeration<String> getAttributeNames() {return Collections.enumeration(this.attributes.keySet());}@SuppressWarnings(value = "deprecated")@Overridepublic String[] getValueNames() {return this.attributes.keySet().toArray(new String[0]);}@Overridepublic void setAttribute(String name, Object value) {this.attributes.put(name, value);}@SuppressWarnings(value = "deprecated")@Overridepublic void putValue(String name, Object value) {this.attributes.put(name, value);}@Overridepublic void removeAttribute(String name) {this.attributes.remove(name);}@Overridepublic void removeValue(String name) {this.attributes.remove(name);}@Overridepublic void invalidate() {this.attributes.clear();}@Overridepublic boolean isNew() {return this.isNew;}public void setId(String id) {this.id = id;}public void setLastAccessedTime(long lastAccessedTime) {this.lastAccessedTime = lastAccessedTime;this.isNew = false;}public void setResponseEndTime(long responseEndTime) {this.responseEndTime = responseEndTime;}public long getResponseEndTime() {return this.responseEndTime;}public Map<String, Object> getAttributes() {return this.attributes;}public boolean isExpired() {return (System.currentTimeMillis() - this.creationTime) / 1000 >= this.maxInactiveInterval;}@Overridepublic String toString() {return this.toMap().toString();}public Map<String, Object> toMap() {Map<String, Object> map = new LinkedHashMap<>();map.put("id", this.id);map.put("creationTime", this.creationTime);map.put("maxInactiveInterval", this.maxInactiveInterval);map.put("lastAccessedTime", this.lastAccessedTime);map.put("responseEndTime", this.responseEndTime);map.put("isNew", this.isNew);map.put("isExpired", this.isExpired());map.put("attributes", this.attributes);return map;}
}
package com.kongjs.emo.web.session.wrapper;import com.kongjs.emo.web.session.Session;
import com.kongjs.emo.web.session.manager.SessionManager;import javax.servlet.ServletContext;
import javax.servlet.SessionCookieConfig;
import javax.servlet.http.*;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
// 实现HttpServletRequestWrapper 托管session
public class RequestSessionWrapper extends HttpServletRequestWrapper {private final HttpServletRequest request;private final HttpServletResponse response;private final SessionManager sessionManager;private String requestedSessionId;private boolean requestedSessionCookie;private boolean requestedSessionURL;public RequestSessionWrapper(HttpServletRequest request, HttpServletResponse response, SessionManager sessionManager) {super(request);this.request = request;this.response = response;this.sessionManager = sessionManager;}@Overridepublic HttpServletRequest getRequest() {return request;}public HttpServletResponse getResponse() {return response;}public SessionManager getSessionManager() {return sessionManager;}private String readCookieValue(ServletContext servletContext) {SessionCookieConfig cookieConfig = servletContext.getSessionCookieConfig();if (this.getCookies() != null) {for (Cookie cookie : this.getCookies()) {if (cookie.getName().equals(cookieConfig.getName())) {this.requestedSessionCookie = true;this.requestedSessionURL = false;return cookie.getValue();}}}String id = this.getRequest().getParameter(cookieConfig.getName());if (id != null && id.length() > 0) {this.requestedSessionCookie = false;this.requestedSessionURL = true;return id;}return null;}private void writeCookieValue(ServletContext servletContext, String value) {SessionCookieConfig cookieConfig = servletContext.getSessionCookieConfig();StringBuilder sb = new StringBuilder();sb.append(cookieConfig.getName()).append('=');if (value != null && value.length() > 0) {sb.append(value);}int maxAge = cookieConfig.getMaxAge();if (maxAge > -1) {sb.append("; Max-Age=").append(maxAge);ZonedDateTime expires = (maxAge != 0) ? ZonedDateTime.now(ZoneId.systemDefault()).plusSeconds(maxAge) : Instant.EPOCH.atZone(ZoneOffset.UTC);sb.append("; Expires=").append(expires.format(DateTimeFormatter.RFC_1123_DATE_TIME));}String domain = cookieConfig.getDomain();if (domain != null && domain.length() > 0) {sb.append("; Domain=").append(domain);}String path = cookieConfig.getPath();if (path != null && path.length() > 0) {sb.append("; Path=").append(path);}//sb.append("; Secure");sb.append("; HttpOnly");sb.append("; SameSite=").append("Lax");response.addHeader("Set-Cookie", sb.toString());}private HttpSession newSession() {Session session = this.getSessionManager().createSession(this.getServletContext());this.getSessionManager().save(session);this.writeCookieValue(this.getServletContext(), session.getId());this.requestedSessionId = session.getId();return session;}@Overridepublic HttpSession getSession(boolean create) {String authorization = this.getRequest().getHeader("Authorization");String id = this.readCookieValue(this.getServletContext());if (id != null) {Session session = this.getSessionManager().findById(id);if (session != null) {if (session.isExpired()) {this.sessionManager.deleteById(id);HttpSession httpSession = this.newSession();this.requestedSessionId = httpSession.getId();return httpSession;}session.setLastAccessedTime(System.currentTimeMillis());this.getSessionManager().save(session);this.requestedSessionId = id;return session;}}if (create) {HttpSession httpSession = this.newSession();this.requestedSessionId = httpSession.getId();return httpSession;}return null;}@Overridepublic HttpSession getSession() {return this.getSession(true);}@Overridepublic String getRequestedSessionId() {return this.requestedSessionId;}@Overridepublic String changeSessionId() {HttpSession httpSession = this.getSession();Session session = (Session) httpSession;session.setId(this.getSessionManager().idGenerator());this.getSessionManager().save(session);this.requestedSessionId = session.getId();return session.getId();}@Overridepublic boolean isRequestedSessionIdValid() {return this.requestedSessionId != null;}@Overridepublic boolean isRequestedSessionIdFromCookie() {return this.requestedSessionCookie;}@Overridepublic boolean isRequestedSessionIdFromURL() {return this.requestedSessionURL;}@Overridepublic boolean isRequestedSessionIdFromUrl() {return this.isRequestedSessionIdFromURL();}
}
package com.kongjs.emo.web.session.manager;import cn.hutool.core.util.IdUtil;
import com.kongjs.emo.web.session.Session;
import com.kongjs.emo.web.session.manager.SessionManager;
import org.springframework.stereotype.Component;import javax.servlet.ServletContext;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
// session 容器管理
public interface SessionManager {String idGenerator();Session createSession(ServletContext servletContext);void save(Session session);Session findById(String id);Session deleteById(String id);List<Session> findAll();List<Session> findByAttributeEquals(String name, String value);List<Session> findByAttributeContain(String name, String value);
}
@Component
public class MapSessionManager implements SessionManager {private final Map<String, Session> sessionMap = new ConcurrentHashMap<>();@Overridepublic String idGenerator() {return IdUtil.getSnowflakeNextIdStr();}@Overridepublic Session createSession(ServletContext servletContext) {return new Session(servletContext, idGenerator());}@Overridepublic void save(Session session) {this.sessionMap.put(session.getId(), session);}@Overridepublic Session findById(String id) {return this.sessionMap.get(id);}@Overridepublic Session deleteById(String id) {return this.sessionMap.remove(id);}@Overridepublic List<Session> findAll() {return new ArrayList<>(this.sessionMap.values());}@Overridepublic List<Session> findByAttributeEquals(String name, String value) {return this.sessionMap.values().stream().filter(m -> m.getAttribute(name) != null && m.getAttribute(name).equals(value)).collect(Collectors.toList());}@Overridepublic List<Session> findByAttributeContain(String name, String value) {return this.sessionMap.values().stream().filter(m -> m.getAttribute(name) != null && m.getAttribute(name).toString().contains(value)).collect(Collectors.toList());}
}
package com.kongjs.emo.web.session.filter;import com.kongjs.emo.web.session.Session;
import com.kongjs.emo.web.session.wrapper.RequestSessionWrapper;
import com.kongjs.emo.web.session.wrapper.ResponseSessionWrapper;
import com.kongjs.emo.web.session.manager.SessionManager;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@Order(SessionFilter.DEFAULT_ORDER)
@Component
public class SessionFilter extends OneFilter {public static final int DEFAULT_ORDER = Integer.MIN_VALUE + 50;private final SessionManager sessionManager;public SessionFilter(SessionManager sessionManager) {this.sessionManager = sessionManager;}
// 拦截session @Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {final RequestSessionWrapper requestSessionWrapper = new RequestSessionWrapper(request, response, sessionManager);final ResponseSessionWrapper responseSessionWrapper = new ResponseSessionWrapper(request, response);Session session = (Session) requestSessionWrapper.getSession(false);try {filterChain.doFilter(requestSessionWrapper, responseSessionWrapper);} finally {if (session != null) {session.setResponseEndTime(System.currentTimeMillis());}}}
}
package com.kongjs.emo.web.controller;import com.kongjs.emo.web.session.Session;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
// 测试
@RestController
@RequestMapping("/session")
public class SessionController {@RequestMapping("/info")public Object session(HttpServletRequest request) {Session session = (Session) request.getSession();return session.toMap();}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/2541.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

20240424codeforces刷题题解

240424刷题题解 Walk on Matrix CodeForces - 1332D 思路 构造题&#xff0c;每个 d p i , j dp_{i,j} dpi,j​​​都是由其左上方向中的按位与最大值决定的。 我们需要从使得贪心解与正确解的差值为 k k k。 为了方便获得 k k k&#xff0c;可以考虑构造一个贪心解为 0…

Windows批处理脚本,用于管理Nginx服务器

先看截图&#xff1a; Windows批处理脚本&#xff0c;用于管理Nginx服务器。它提供了启动、重启、关闭Nginx以及刷新控制台等功能。 设置环境变量&#xff1a; set NGINX_PATHD:&#xff1a;设置Nginx所在的盘符为D盘。set NGINX_DIRD:\nginx1912\&#xff1a;设置Nginx所在…

HTML5+CSS3小实例:炫彩荧光线条登录框

实例:炫彩荧光线条登录框 技术栈:HTML+CSS 效果: 源码: 【HTML】 <!DOCTYPE html> <html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-sca…

每日一题---环形链表的约瑟夫问题

文章目录 前言1.题目2.解题思路2.1创建节点 2.2.创建环形链表2.3.进行遍历 4参考代码 前言 前段时间我们学习到了单链表和双向链表的相关知识&#xff0c;下面我们解决一道具有代表性的一个编程题。 牛客网—环形链表的约瑟夫问题 1.题目 2.解题思路 2.1创建节点 //创建节点…

flink入门程序(一)

Flink中提供了3个组件&#xff0c;包括DataSource、Transformation和DataSink。 DataSource&#xff1a;表示数据源组件&#xff0c;主要用来接收数据&#xff0c;目前官网提 供了readTextFile、socketTextStream、fromCollection以及一些第三方的Source。 Transformation&…

scratch选择火车下铺 2024年3月中国电子学会图形化编程 少儿编程 scratch编程等级考试四级真题和答案解析

目录 scratch根据身份证号码识别是否优先选择火车下铺 一、题目要求 1、准备工作 2、功能实现 二、案例分析

25计算机考研院校数据分析 | 复旦大学

复旦大学(fudan University)&#xff0c;简称"复旦”&#xff0c;位于中国上海&#xff0c;由中华人民共和国教育部直属&#xff0c;中央直管副部级建制&#xff0c;位列985工程、211工程、双一流A类&#xff0c;入选“珠峰计划"、"111计划""2011计划…

理解CSS中的sticky与fixed定位

在CSS中&#xff0c;position: sticky; 和 position: fixed; 是两种常见的定位方式&#xff0c;它们可以让元素脱离文档流&#xff0c;并具有固定位置的效果。然而&#xff0c;它们在实际应用中有着不同的特点和使用场景。 sticky定位 特点&#xff1a;position: sticky; 允许…

【学习】软件测试自动化,是未来的趋势还是当前的必需

在当今快速迭代的软件开发周期中&#xff0c;速度和质量成为了企业生存的关键。随着DevOps实践的普及和持续集成/持续部署&#xff08;CI/CD&#xff09;流程的标准化&#xff0c;软件测试自动化已经从未来的趋势转变为当前的必要性。本文将探讨自动化测试的现状、必要性以及其…

【node:19212】 解决 Node.js 报错 “将文件视为 CommonJS 模块“

【node:19212】 解决 Node.js 报错 “将文件视为 CommonJS 模块” 当在 Node.js 中运行 JavaScript 文件时&#xff0c;可能会遇到类似以下的报错信息&#xff1a; (node:19212) Warning: To load an ES module, set "type": "module" in the package.js…

uniapp 引用组件后 不起作用 无效果 不显示

根据uniapp官方文档easycom组件规范 只要组件安装在项目的components目录下或uni_modules目录下&#xff0c;并符合components/组件名称/组件名称.(vue|uvue)目录结构&#xff08;注意&#xff1a;当同时存在vue和uvue时&#xff0c;uni-app 项目优先使用 vue 文件&#xff0c;…

【C语言__指针02__复习篇12】

目录 前言 一、数组名的理解 二、使用指针访问数组 三、一维数组传参的本质 四、冒泡排序 五、二级指针 六、指针数组 七、指针数组模拟二维数组 前言 本篇主要讨论以下问题&#xff1a; 1. 数组名通常表示什么&#xff0c;有哪两种例外情况&#xff0c;在例外情况中…

Retelling|Gap Year

录音 Retelling|Gap Year gap year 转写 im a trainee from DJ teaching interpretation. And Im going to talk about taking a gap year. Its Most of our popular off for students are taken after college and before University, the UK taking a cut cups here and hav…

我用ADAU1467加5个ADAU1772,做20进10出的音频处理板(七):音量调节的更多例程

作者的话 ADAU1467是现阶段ADI支持最多通道的ADAU音频DSP&#xff0c;他配合外部的AD/DA&#xff0c;可以实现最多32路音频通道&#xff0c;接了一个小项目&#xff0c;我拿它做了一块20进10出的板&#xff0c;10个MIC/LINE输入,10个LINE IN输入&#xff0c;10个HPOUT&#xf…

烟雾识别图像处理:原理、应用与未来发展---豌豆云

本文详细介绍了烟雾识别图像处理的基本原理、应用领域以及未来的发展趋势。 通过深入剖析烟雾识别图像处理的关键技术和方法&#xff0c;帮助读者了解该领域的最新进展&#xff0c;为实际应用提供有价值的参考。 随着计算机视觉和人工智能技术的快速发展&#xff0c;烟雾识别…

贪心算法在单位时间任务调度问题中的应用

贪心算法在单位时间任务调度问题中的应用 一、引言二、问题描述与算法设计三、算法证明四、算法实现与效率分析五、C语言实现示例六、结论 一、引言 单位时间任务调度问题是一类经典的优化问题&#xff0c;旨在分配任务到不同的时间槽中&#xff0c;使得某种性能指标达到最优。…

Git和Github绑定

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

Qt 菜单栏上手教程:QMenuBar QMenu QToolbar

引言 在Qt框架中&#xff0c;QMenuBar、QMenu、QToolbar和QAction都是用于构建应用程序界面中的用户交互元素。 QMenuBar 是什么&#xff1a;QMenuBar是一个用于创建横向菜单栏的类。在桌面应用程序中&#xff0c;它通常位于窗口的顶部。应用场景&#xff1a;当您需要一个包含…

关于Spring事务管理之默认事务间调用问题

由事务的传播行为我们知道, 如果将方法配置为默认事务REQUIRED在执行过程中Spring会为其新启事务REQUIRES_NEW, 作为一个独立事务来执行. 由此存在一个问题。 如果使用不慎, 会引发org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back bec…

新技术前沿-2024-大型语言模型LLM的本地化部署

参考快速入门LLM 参考究竟什么是神经网络 1 深度学习 1.1 神经网络和深度学习 神经网络是一种模拟人脑神经元工作方式的机器学习算法,也是深度学习算法的基本构成块。神经网络由多个相互连接的节点(也称为神经元或人工神经元)组成,这些节点被组织成层次结构。通过训练,…