自己实现httpsession

ops/2024/10/11 13:28:09/
java">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;}
}
java">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();}
}
java">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());}
}
java">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());}}}
}
java">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.ppmy.cn/ops/14276.html

相关文章

【linux】进程地址被占用

在强制关闭一个udp程序后&#xff0c;重启该程序报错&#xff1a; bind error: Address already in use 查找并关闭占用端口的进程&#xff1a; 首先&#xff0c;确定哪个进程占用了目标端口。在Linux系统中&#xff0c;可以使用以下命令&#xff1a; netstat -tulnp | grep …

springboot 集成 i18n实现国际化信息返回 实现中英文切换 实现网站支持多语言切换

还是直接上代码 目前实现了 中英文 返回 别的语言 都差不多 主要用spring boot 自带的 类实现的 不用引入任何 依赖 使用的就是下面的类 org.springframework.context.MessageSource 是 Spring Framework 中用于支持国际化&#xff08;Internationalization&#xff0c;简称 i…

智能驾驶+网络安全

在智能驾驶场景下&#xff0c;安全问题一直是一个持续热点。 针对车机模块不被黑客利用Linux的漏洞攻击&#xff0c;可以采取以下几种方式来提高安全性&#xff1a; 安全设计和防护&#xff1a;在设计车机模块时&#xff0c;需要考虑安全性&#xff0c;并采取相应的安全防护措施…

解决 Tomcat 跨域问题 - Tomcat 配置静态文件和 Java Web 服务(Spring MVC Springboot)同时允许跨域

解决 Tomcat 跨域问题 - Tomcat 配置静态文件和 Java Web 服务&#xff08;Spring MVC Springboot&#xff09;同时允许跨域 Tomcat 配置允许跨域Web 项目配置允许跨域Tomcat 同时允许静态文件和 Web 服务跨域 偶尔遇到一个 Tomcat 部署项目跨域问题&#xff0c;因为已经处理过…

基于vscode的c++开发(Windows)

文章目录 开发环境搭建项目文件夹GCC编译器编译过程g的重要编译参数 CMake语法特性重要指令CMake编译工程 参考链接 开发环境搭建 安装VScode和GCC编译器。 项目文件夹 一般一个项目中应该包含 include文件夹——用于保存头文件 src文件夹——用于保存源文件 GCC编译器 GC…

SpringBoot钩子函数

在Java Spring Boot中&#xff0c;并没有直接称为“钩子函数”的概念&#xff0c;但你可以通过实现特定的接口、注解、事件监听或使用AOP&#xff08;面向切面编程&#xff09;来实现类似的功能。这些功能允许你在应用的特定点插入自定义逻辑&#xff0c;类似于钩子函数的作用。…

CTFshow-PWN-栈溢出(pwn44)

64位的 system(); 但是好像没"/bin/sh" 上面的办法不行了&#xff0c;想想办法 检查&#xff1a; 是 64 位程序 ida 反编译 main 函数&#xff1a; 跟进 ctfshow 函数&#xff1a; 存在栈溢出 offset&#xff1a;0xAh8 在前面经验的基础上&#xff0c;这里我们直…

DataGrip操作Oracle

一、创建表空间 表名任意起&#xff0c;路径自己指定 -- 创建表空间 create tablespace mydb1 -- 表名 datafile E:\Code\sql\oracle\oracle_tablespace\mydb1.dbf --指定表空间路径 size 100M --指定表空间大小 autoextend on next 50M --指定一次扩充多少mb extent managemen…