总体思想:
掉用的时候直接调用代理实例对象获取即可,用拦截器,或者直接把HttpServletRequestWrapper替换掉
package com.houbank.session.filter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.util.logging.resources.logging;
import lombok.extern.java.Log;
import lombok.extern.log4j.Log4j2;
import com.houbank.session.manager.RedisTemplateDelegate;
import com.houbank.session.manager.WebSession;
import com.houbank.session.manager.WebSessionManager;
类1
/**
*
* <p>通过继承HttpServletRequestWrapper 来实现</p>
* @author houzhanshan
* @version $Id: RemoteSessionRequest.java, v 0.1 2017年5月26日 下午11:40:51 houzhanshan Exp $
*/
public class RemoteSessionRequest extends HttpServletRequestWrapper {
public RemoteSessionRequest(HttpServletRequest request) {
super(request);
}
//复写getSession方法,外界使用的方法,每次用到session的时候,拿到系统自带的session,建立自己的代理session
@Override
public HttpSession getSession() {
return RemoteSessionHandler.getInstance(super.getSession());
}
}
类2
动态代理session
@Log4j2
class RemoteSessionHandler implements InvocationHandler {
// 模拟远程Session服务器,Key表示SessionId,Value表示该Session的内容
private static Map<String, Map<String, Object>> map = new ConcurrentHashMap<String, Map<String, Object>>();
private static Logger log= LoggerFactory.getLogger(RedisTemplateDelegate.class);
private HttpSession session = null;
private RemoteSessionHandler(HttpSession httpSession) {
this.session = httpSession;
};
//静态方法
//获取实例代理实例,调用代理
public static HttpSession getInstance(HttpSession httpSession) {
//获取代理处理器实例
InvocationHandler handler = new RemoteSessionHandler(httpSession);
//调用代理
return (HttpSession) Proxy.newProxyInstance(httpSession.getClass().getClassLoader(), httpSession.getClass().getInterfaces(), handler);
}
//切入方法点
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("setAttribute".equals(method.getName())) {
String id = session.getId();
Map<String, Object> m = map.get(id);
if (m == null) {
m = new HashMap<String, Object>();
}
WebSession webSession=WebSessionManager.getInstance().getSession(id);
if(webSession==null){
webSession=WebSessionManager.getInstance().createSession(id);
}else{
webSession=WebSessionManager.getInstance().getSession(id);
}
webSession.setAttribute((String) args[0], args[1]);
log.info("[存入]key:" + args[0] + ",value:" + args[1]);
return null;
} else if ("getAttribute".equals(method.getName())) {
String id = session.getId();
WebSession webSession= WebSessionManager.getInstance().getSession(id);
if(webSession==null){
return null;
}
Object result = webSession.getAttribute((String) args[0]);
log.info("[取出]key:" + args[0] + ",value:" + result);
return result;
}
return method.invoke(session, args);
}
}
每次请求的时候重置里面的request,改变拿到request的具体对象,从而改变拿到的session,改变拿值的地方
都有这么一个链,加入过滤器链,不管在哪个顺序,总是在调用资源之前,此时的就都做了,也就在具体资源要用之前就被过滤了(替换成自定义)
@WebFilter("/*")
public class SessionFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//chain就是过滤器链,dofilter就是向下一个链执行
chain.doFilter(new RemoteSessionRequest((HttpServletRequest) request), response);
}
此时需要
HttpServletRequest request1 = (HttpServletRequest) request;
HttpSession session = request1.getSession();
代理HttpSession生成RemoteSessionRequest.java
用这个方法就弄好了session的拦截处理
过滤器:
chain.doFilter(request,response)
一般filter都是一个链,web.xml 里面配置了几个就有几个。一个一个的连在一起
request -> filter1 -> filter2 ->filter3 -> .... -> request resource.
可以提前跳转后return null,也可
附件说明:
core.session.filter
core.session.manager
core.monitor 拦截器
RemoteSessionRequest.java 包装session
SessionFilter.java拦截把包装好的request放入代替原有的request(代替requset用过滤器)(实现redis的单点登录内存session共享),代替框架中的实现类用回调机制,
这样可以代替一切
core.session.filter 代换requset 通过WebSessionManager用自己的session
core.session.manager 代换的里面用的redis(具体换requset的点)
WebUtils.java 获取bean
WebSessionManager.java 管理session
WebSessionManager.java session的具体构造
RedisTemplateDelegate.java 用的redis模板
WebSession.java
也就是存每个用户session,及每个用户session拥有的属性,这样模拟了sso
public void setAttribute(String name, Object value) {
this.attributes.put(name, value);k-v
storageSet(this.storageId, this.attributes); sessionid-v redis中存sessionid 和map对象(装初始k-y和后面增加的k-v)
} 存在内存中,存在redis中
一个用户一个WebSession对象(一个sessionid一个对象),即自定义session,每个session操作更新attributes,保存redis
获取session--->通过sessionid 获取 attributes然后组装成session对象WebSession
后期修改通过sessionid,获取本session,之后调用session内部的操作attributes方法处理本session
相关推荐
通过以上步骤,你就可以成功地将session信息从本地内存迁移到Redis中,实现跨服务器的session共享,从而提高Web应用的可扩展性。这是一个非常实用的技术,尤其是在大型分布式系统中。在实际应用中,你可能还需要根据...
要实现Spring Boot分布式Session与Redis的整合,我们需要以下几个步骤: 1. **添加依赖**: 首先在`pom.xml`或`build.gradle`文件中添加Spring Session和Redis的依赖。对于Maven,可以添加如下依赖: ```xml ...
要实现SpringBoot项目中的Redis Session共享,首先需要在项目中添加必要的依赖。需要在`pom.xml`文件中引入`spring-boot-starter-data-redis`和`spring-session-data-redis`这两个依赖。这两个依赖分别提供了Spring ...
Spring-Session可以通过将Session数据存储在Redis这样的分布式存储中,实现不同应用间Session的共享,从而达到SSO的效果。 **Spring-Session与Redis的结合** Spring-Session通过将Session数据持久化到Redis,确保...
而本文将详细介绍使用Redis作为共享存储的方案——`tomcat-redis-session-manager`。 #### 必要环境准备 为了顺利实施这一方案,首先需要准备以下环境: - **Java版本**:Java 1.7 或更高版本。 - **Tomcat版本**...
你可以自定义实现这个接口,但通常我们会选择使用RedisSessionRepository,它将session数据存储在Redis中。 2. **HttpSessionBindingListener**: 这是Spring Session对标准JavaEE HttpSession接口的增强,它监听...
- Session集中存储:使用共享的Session存储(如数据库或缓存),所有服务器都从同一位置读写Session。 **总结**: Session是Web开发中不可或缺的部分,它有效地解决了HTTP无状态协议的限制,为用户提供了一种保持...
如果你的应用有多个子域名,可能需要跨域共享Session。可以通过设置`'domain'`配置项为`.yourdomain.com`来实现。 9. **处理Session过期** 当用户长时间不活动时,Session会自动过期。你可以通过`'lifetime'`配置...
下 Session 都是共享的。 <!-- 用户信息记住我功能的相关配置 --> <!-- 配置存储rememberMe Cookie的domain为 一级域名 --> <property name="maxAge" value="2592000"/><!-- 30天时间,...
* 扩展指定 server,利用 Servlet 容器提供的插件功能,自定义 HttpSession 的创建和管理策略。 * 利用 Filter,实现自己的 getSession() 方法,接管创建和管理 Session 数据的工作。 * 使用 Spring Session 的支持...
1. **PHP会话管理**:PHP会话是保持用户状态的一种方式,通常通过在服务器端存储数据(如`$_SESSION`全局变量)并在多个页面请求之间共享来实现。 2. **面向对象编程**:面向对象编程(OOP)是一种编程范式,它将...
9. **分布式会话管理**:在集群环境中,会话需要在多台服务器之间共享,这时可以使用像Memcached或Redis这样的缓存系统进行分布式会话管理。 10. **ServletContext作用域**:除了Session,JSP还有其他作用域,如...
Spring Bean有singleton、prototype、request、session等作用域,其生命周期包括初始化、使用和销毁。Spring Boot简化了Spring应用的配置和启动过程,Spring 5相比Spring 4增强了Reactor支持和HTTP/2等特性。 ...
在微服务架构中,可以通过使用集中式的 Session 存储方案(如 Redis)来实现 session 共享。这种方式可以确保不同服务实例间共享 session 数据。 **6.12 Spring Boot 中如何实现定时任务?** Spring Boot 支持通过...
- **分布式session**: 由于单台服务器无法满足大量并发请求,需将session数据保存在分布式系统中(如Redis、数据库等),确保在集群环境下各服务器间可以共享session信息。 **JDBC流程** 1. 加载数据库驱动; 2. ...
- **内置对象:** 如Request、Response、Session、Application等。 - **应用程序配置:** 设置web.config文件以配置应用程序的行为。 - **缓存管理:** 使用输出缓存和数据缓存提高网站性能。 - **第14章 ASP...
JSP通过内置对象(如Request、Response、Session等)处理HTTP请求,实现数据的接收与响应,同时利用JSP标签库(JSTL)和自定义标签来简化页面逻辑,提高代码的可读性和可维护性。 2. Java Web开发技术:这通常包括...
例如,日志记录、事务管理等功能可以通过AOP来实现,从而避免在业务逻辑中重复编写相同的代码。 7. **Spring支持的事务管理类型** - Spring支持两种类型的事务管理:编程式事务管理和声明式事务管理。编程式事务...
除了基本操作外,FizeSession还支持自定义会话ID生成器、自定义过期策略、中间件集成等高级功能。例如,你可以通过继承`SessionMiddleware`类并覆盖`process_request`和`process_response`方法,将FizeSession集成到...
微信公众号管理平台,除实现官网后台自动回复、菜单管理、素材管理、用户管理、消息群发等基础功能外,还有二维码推广、营销活动、微网站、会员卡、优惠券等。 > zheng-wechat-app 微信小程序后台 ## 环境搭建...