Spring Session + Redis 实现session共享

关于Spring Session + Redis实现session共享的问题网上有很多案例,但是尝试好久最终都没有解决问题,建议大家还是去官网看一下,如何实现https://docs.spring.io/spring-session/docs/1.3.0.RELEASE/reference/html5/#httpsession-redis

官网提供了两种方式:1.Java Based Configuration基于Java的配置;2.XML Based Configuration基于XML的配置。如下图黄色区域:

这里主要介绍一下基于xml的配置:

1. pom.xml文件中引入所需依赖

<!-- spring-session begin-->
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-redis</artifactId>
        <version>1.7.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.session</groupId>
        <artifactId>spring-session</artifactId>
        <version>1.3.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>2.8.1</version>
    </dependency>

2.Redis配置文件中配置以下信息(注:官网中说配置LettuceConnectionFactory信息,或者其他文档中说配置JedisConnectionFactory信息,都是一个意思,其实LettuceConnectionFactoryJedisConnectionFactory都实现了RedisConnectionFactory接口,具体查看https://www.2cto.com/kf/201705/638410.html):

        <bean id="connectionFactory"
		    class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
		p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}"
		p:pool-config-ref="poolConfig" p:database="14"/>
	<bean id="redisHttpSessionConfiguration"
		  class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
		<property name="maxInactiveIntervalInSeconds" value="9999999" />
	</bean>

通过官网上“We use the combination of <context:annotation-config/> and RedisHttpSessionConfiguration because Spring Session does not yet provide XML Namespace support (see gh-104). This creates a Spring Bean with the name of springSessionRepositoryFilter that implements Filter. The filter is what is in charge of replacing the HttpSession implementation to be backed by Spring Session. In this instance Spring Session is backed by Redis.”这段话可知,RedisHttpSessionConfiguration的id必须是redisHttpSessionConfiguration

3.其他地方大多数都是在web.xml中配置过滤器,如下配置:

<!-- spring-session -->
<filter>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>ERROR</dispatcher>
</filter-mapping>

在这是通过java配置过滤器,只要继承org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer抽象类即可,在这个类中会自动装配。重写beforeSessionRepositoryFilter方法和afterSessionRepositoryFilter方法。

beforeSessionRepositoryFilter方法,加载的是必要信息;afterSessionRepositoryFilter方法添加一些自己配置的过滤器。

    @Override
    protected void beforeSessionRepositoryFilter(ServletContext servletContext) {
        // Create the dispatcher servlet's Spring application context
        AnnotationConfigWebApplicationContext dispatcherServlet = new AnnotationConfigWebApplicationContext();
        dispatcherServlet.register(MvcConfig.class);
        dispatcherServlet.setServletContext(servletContext);
        servletContext.addListener(new ContextLoaderListener(dispatcherServlet));
        dispatcherServlet.scan("com.qxs.web.config.MvcConfig");

	ServletRegistration.Dynamic registration = servletContext.addServlet("dispatcher", new DispatcherServlet(dispatcherServlet));
        registration.setLoadOnStartup(1);
        registration.addMapping("/");
    }
    @Override
    protected void afterSessionRepositoryFilter(ServletContext servletContext) {
        DelegatingFilterProxy delegatingFilterProxy = new DelegatingFilterProxy();
        servletContext.addFilter("shiroFilter", delegatingFilterProxy)
		 .addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*");

        //add UTF-8 filter
        final CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("UTF-8");
        characterEncodingFilter.setForceEncoding(false);
        servletContext.addFilter("characterEncodingFilter", characterEncodingFilter)
        			 .addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*");

        //Todo - add SiteMeshFilter

        SiteMeshFilter siteMeshFilter = new SiteMeshFilter();
        servletContext.addFilter("siteMeshFilter", siteMeshFilter)
		 .addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*");

        OpenEntityManagerInViewFilter openEntityManagerInViewFilter = new OpenEntityManagerInViewFilter();
        openEntityManagerInViewFilter.setEntityManagerFactoryBeanName("entityManagerFactory");
        servletContext.addFilter("openEntityManagerInViewFilter", openEntityManagerInViewFilter)
		 .addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*");
    }

4.在启动的过程中会运行AbstractHttpSessionApplicationInitializer的onStartup(ServletContext sevletContext)方法,调用insertSessionRepositoryFilter方法,然后装配springSessionRepositoryFilter过滤器。

至此,Spring Session + Redis 实现共享session就结束了。













  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
使用SpringBoot框架结合MyBatis实现Session共享和单点登录可以借助SpringSessionRedis实现。 首先,需要配置SpringSession以使用Redis作为存储方式。可以在SpringBoot的配置文件中添加以下配置: ``` spring.session.store-type=redis spring.session.redis.namespace=spring:session spring.redis.host=127.0.0.1 spring.redis.port=6379 ``` 这样配置后,SpringSession会自动将session信息存储到Redis中。 接着,在登录验证成功后,将用户信息存储到Redis中,并将该用户的唯一标识存储到当前Session的属性中,以便后续验证是否登录。例如: ``` @RequestMapping("/login") public String login(@RequestParam("username") String username, @RequestParam("password") String password, HttpSession session) { // 验证用户名和密码 // ... // 验证通过后,将用户信息存储到Redis中,并设置Session属性 redisTemplate.opsForHash().put("user:" + username, "username", username); session.setAttribute("username", username); return "success"; } ``` 在后续的请求中,可以通过拦截器或过滤器来验证Session是否有效。例如: ``` @Component public class SessionInterceptor implements HandlerInterceptor { @Autowired private RedisTemplate<String, Object> redisTemplate; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HttpSession session = request.getSession(); String username = (String) session.getAttribute("username"); if (StringUtils.isEmpty(username)) { response.sendRedirect("/login"); return false; } String storedUsername = (String) redisTemplate.opsForHash().get("user:" + username, "username"); if (!StringUtils.equals(storedUsername, username)) { response.sendRedirect("/login"); return false; } return true; } } ``` 以上代码片段展示了如何通过拦截器验证Session的有效性。首先从当前Session中获取用户名,如果为空则重定向到登录页面。然后从Redis中获取存储的用户名,如果与当前用户名不匹配,则重定向到登录页面。 这样就实现SpringBoot、MyBatis、SpringSessionRedis共同完成Session共享和单点登录的功能。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值