`
y806839048
  • 浏览: 1107965 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

自定义request以实现共享session的功能(从redis拿)

阅读更多

 

总体思想:

 

掉用的时候直接调用代理实例对象获取即可,用拦截器,或者直接把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信息从本地内存迁移到Redis中,实现跨服务器的session共享,从而提高Web应用的可扩展性。这是一个非常实用的技术,尤其是在大型分布式系统中。在实际应用中,你可能还需要根据...

    38. Spring Boot分布式Session状态保存Redis【从零开始学Spring Boot】

    要实现Spring Boot分布式Session与Redis的整合,我们需要以下几个步骤: 1. **添加依赖**: 首先在`pom.xml`或`build.gradle`文件中添加Spring Session和Redis的依赖。对于Maven,可以添加如下依赖: ```xml ...

    多个SpringBoot项目采用redis实现Session共享功能

    要实现SpringBoot项目中的Redis Session共享,首先需要在项目中添加必要的依赖。需要在`pom.xml`文件中引入`spring-boot-starter-data-redis`和`spring-session-data-redis`这两个依赖。这两个依赖分别提供了Spring ...

    spring-session实现session共享

    Spring-Session可以通过将Session数据存储在Redis这样的分布式存储中,实现不同应用间Session的共享,从而达到SSO的效果。 **Spring-Session与Redis的结合** Spring-Session通过将Session数据持久化到Redis,确保...

    tomcat-redis-session-manager-master文档

    而本文将详细介绍使用Redis作为共享存储的方案——`tomcat-redis-session-manager`。 #### 必要环境准备 为了顺利实施这一方案,首先需要准备以下环境: - **Java版本**:Java 1.7 或更高版本。 - **Tomcat版本**...

    spring-session:spring session+redis实现分布式缓存

    你可以自定义实现这个接口,但通常我们会选择使用RedisSessionRepository,它将session数据存储在Redis中。 2. **HttpSessionBindingListener**: 这是Spring Session对标准JavaEE HttpSession接口的增强,它监听...

    (转)讲解各种session

    - Session集中存储:使用共享的Session存储(如数据库或缓存),所有服务器都从同一位置读写Session。 **总结**: Session是Web开发中不可或缺的部分,它有效地解决了HTTP无状态协议的限制,为用户提供了一种保持...

    Laravel开发-session

    如果你的应用有多个子域名,可能需要跨域共享Session。可以通过设置`'domain'`配置项为`.yourdomain.com`来实现。 9. **处理Session过期** 当用户长时间不活动时,Session会自动过期。你可以通过`'lifetime'`配置...

    SpringMVC-Mybatis-Shiro-redis-master 权限集成缓存中实例

    下 Session 都是共享的。 &lt;!-- 用户信息记住我功能的相关配置 --&gt; &lt;!-- 配置存储rememberMe Cookie的domain为 一级域名 --&gt; &lt;property name="maxAge" value="2592000"/&gt;&lt;!-- 30天时间,...

    详解SpringBoot2 使用Spring Session集群

    * 扩展指定 server,利用 Servlet 容器提供的插件功能,自定义 HttpSession 的创建和管理策略。 * 利用 Filter,实现自己的 getSession() 方法,接管创建和管理 Session 数据的工作。 * 使用 Spring Session 的支持...

    laminas-session:面向对象PHP会话和存储接口

    1. **PHP会话管理**:PHP会话是保持用户状态的一种方式,通常通过在服务器端存储数据(如`$_SESSION`全局变量)并在多个页面请求之间共享来实现。 2. **面向对象编程**:面向对象编程(OOP)是一种编程范式,它将...

    jsp与web状态管理笔记

    9. **分布式会话管理**:在集群环境中,会话需要在多台服务器之间共享,这时可以使用像Memcached或Redis这样的缓存系统进行分布式会话管理。 10. **ServletContext作用域**:除了Session,JSP还有其他作用域,如...

    20-BAT面试题汇总及详解(进大厂必看).docx

    Spring Bean有singleton、prototype、request、session等作用域,其生命周期包括初始化、使用和销毁。Spring Boot简化了Spring应用的配置和启动过程,Spring 5相比Spring 4增强了Reactor支持和HTTP/2等特性。 ...

    Spring Boot面试题(2022最新版)-重点

    在微服务架构中,可以通过使用集中式的 Session 存储方案(如 Redis)来实现 session 共享。这种方式可以确保不同服务实例间共享 session 数据。 **6.12 Spring Boot 中如何实现定时任务?** Spring Boot 支持通过...

    面试宝典总结

    - **分布式session**: 由于单台服务器无法满足大量并发请求,需将session数据保存在分布式系统中(如Redis、数据库等),确保在集群环境下各服务器间可以共享session信息。 **JDBC流程** 1. 加载数据库驱动; 2. ...

    邮件系统源码

    JSP通过内置对象(如Request、Response、Session等)处理HTTP请求,实现数据的接收与响应,同时利用JSP标签库(JSTL)和自定义标签来简化页面逻辑,提高代码的可读性和可维护性。 2. Java Web开发技术:这通常包括...

    SSM框架面试题.pdf

    例如,日志记录、事务管理等功能可以通过AOP来实现,从而避免在业务逻辑中重复编写相同的代码。 7. **Spring支持的事务管理类型** - Spring支持两种类型的事务管理:编程式事务管理和声明式事务管理。编程式事务...

    FizeSession:FizeSession参考手册

    除了基本操作外,FizeSession还支持自定义会话ID生成器、自定义过期策略、中间件集成等高级功能。例如,你可以通过继承`SessionMiddleware`类并覆盖`process_request`和`process_response`方法,将FizeSession集成到...

    单点登录源码

    微信公众号管理平台,除实现官网后台自动回复、菜单管理、素材管理、用户管理、消息群发等基础功能外,还有二维码推广、营销活动、微网站、会员卡、优惠券等。 &gt; zheng-wechat-app 微信小程序后台 ## 环境搭建...

Global site tag (gtag.js) - Google Analytics