Spring-session redis 子域名 session

摘要:
--设置cookie域和名称--˃˂!

Spring-session & redis 子域名共享session

例子:

a.example.com
b.example.com
Spring 版本 4.2.6.RELEASE
Spring-session Maven 依赖相关的包

<!-- redis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.7.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>1.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.2</version>
</dependency>

redis.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"
default-autowire="byName" default-lazy-init="true">

<!-- redis -->
<bean class="redis.clients.jedis.JedisPoolConfig">
</bean>

<!-- 设置Cookie domain 和 名称 -->
<bean class="org.springframework.session.web.http.DefaultCookieSerializer">
<property name="domainName" value=".example.com"/>
<property name="cookieName" value="JSESSIONID"/>
<!--<property name="domainNamePattern" value="^.+?\.(\w+\.[a-z]+)$"/>-->
</bean>

<bean id="jedisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="${redis.host}" />
<property name="port" value="${redis.port}" />
<property name="password" value="${redis.pass}" />
<property name="timeout" value="${redis.timeout}" />
<property name="poolConfig" ref="jedisPoolConfig" />
<property name="usePool" value="true" />
</bean>

<bean class="org.springframework.data.redis.core.StringRedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory" />
</bean>

<!-- 将session放入redis -->
<bean id="redisHttpSessionConfiguration"
class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
<property name="maxInactiveIntervalInSeconds" value="1800" />
<property name="cookieSerializer" ref="defaultCookieSerializer"/>
</bean>

</beans>

以上配置完后,分别启动 a tomcat(a.example.com),b tomcat(b.example.com) 查看sessionid 是否已经一致了 

说道Session共享,从网上搜索,有几种实现方式,比较普遍的 Tomcat Session Redis,这种是需要在tomcat容器里增加几个jar包,并修改Tomcat里的content.xml增加一条语句,实现session共享,此方法依赖于 tomcat.
还有一种是 Spring-Session-Data-Redis,此方法对servlet容器都有效,不局限于tomcat,也是比较普遍的一种方法,具体可自行百度了解
今天要说的是在配置SpringSessionDataRedis过程中遇到的坑
基本配置方式也比较简单
第一步:pom.xml中引入依赖
首先要引入依赖,此依赖并不是jar,而是一个空包里面还有对spring-session,redis等几个必要组件的依赖
<!-- https://mvnrepository.com/artifact/org.springframework.session/spring-session-data-redis -->
<dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
            <version>1.3.1.RELEASE</version>
</dependency>
注意:此地方有一个比较坑爹地方,当打开Maven仓库,可以看到有一个对Spring版本的依赖的要求,对于1.3.1的SpringSession,对Spring的依赖最低4.3.4,如果依赖低于这个版本,则会报错Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.session.SessionRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}, 特别注意,引入不同的版本时,可能会引起原有jar包版本不兼容
第二步:Spring-mvc.xml中增加 redisHttpSessionConfiguration
    <!-- Spring Session Redis 共享 http://www.cnblogs.com/andyfengzp/p/6434287.html -->
     <bean id="redisHttpSessionConfiguration" class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
        <property name="maxInactiveIntervalInSeconds" value="1800"/>
    </bean>
注意:由于使用了这里的配置,由redis负责接管Session,原来web.xml里配置的Session超时时间就会失效了
    <session-config>
        <session-timeout>60</session-timeout>
        <cookie-config>
            <http-only>true</http-only>
        </cookie-config>
    </session-config>

第三步:Web.xml中配置filter

    <!-- Spring Session Redis 共享 需要放在filter的第一个  http://www.cnblogs.com/andyfengzp/p/6434287.html -->
    <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>
    </filter-mapping>
注意:这个filter要写在比较靠前的第一个的位置

以上这几步配置完成后,基本就可以实现Session的共享了。
但是这里还有一个情况,项目启动后,左右的静态资源都无法访问了,这个是和原来的版本有不一样的地方,
Spring4.3,这里需要注意,所有Spring的xml的配置文件里标签要变为  -4.3.xsd
<!-- 静态文件资源访问配置 --> 要注意这里的静态文件不要放到WEB-INF里,要放到项目内,例如项目下的resources
<mvc:resources mapping="/**" location="/resources/" />这样就可以放行静态文件的访问


还有一个比较大的坑,使用Spring Session实际是Spring加入了一个Filter,其本质是:对每一个请求的request都会被DelegatingFilterProxy进行了一次封装。那么,在Controller里面拿出的request实际上是封装后的request,因为Session要存在Session,所以调用request.getSession()的时候,实际上拿到是Spring封装后的session ,因此对于request实际上拿到是Spring封装后的request。那么可能会导致Request.getInputStream无法获取到流数据,对于使用raw格式,即非Key,Value参数的提交 会被Spring-Session获取,当contentType为application/x-www-form-urlencoded时,就会被解析成Paramater,从而导致request.getInputStream的数据再获取时为空了。还有就是Controller里如果用到了request.setCharacterEncoding("GBK"); 设置字符集,这样的请求也无法生效,因为request.setCharacterEncoding只有在request.getSession或者request.getParamater之前使用有效,而由于使用Spring Session加入了filter,所以Controller里的request.setCharacterEncoding这种方式转编码就失效了,解决办法,可以是new String(request.getParameter(key).getBytes(), "GBK"),获取到参数后转码
---------------------

免责声明:文章转载自《Spring-session redis 子域名 session》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇kibana 常用查询方法VS Code C++ 代码格式化方法(clang-format)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

snmp学习笔记

snmp5.5 client 包含头文件 #include <net-snmp/net-snmp-config.h> #include <net-snmp/net-snmp-includes.h> 用到的函数有:初始化snmp库:void init_snmp(const char *); 用于初始化snmp库 netsnmp_ses...

普通Java类获取Spring的bean traceofsun的专栏 博客频道 CSDN.NET

普通Java类获取Spring的bean - traceofsun的专栏 - 博客频道 - CSDN.NET 普通Java类获取Spring的bean 分类:Extjs开发2010-08-13 09:47451人阅读评论(0)收藏举报 在SSH集成的前提下。某些情况我们需要在Action以外的类中来获得Spring所管理的Service对象...

shiro-会话管理

  shiro提供了完整的企业级会话还礼功能,不依赖与底层容器(如web容器Tomcat),不管JavaSE还是JavaEE环境都可以使用,提供了会话管理、会话事件监听、会话存储/持久化、容器无关的集群、失效/过期支持、对web的透明支持,SSO单点登录的支持等特性。 一. 会话相关的API:org.apache.shiro.session.Session...

学习Spring Boot:(二十五)使用 Redis 实现数据缓存

前言 由于 Ehcache 存在于单个 java 程序的进程中,无法满足多个程序分布式的情况,需要将多个服务器的缓存集中起来进行管理,需要一个缓存的寄存器,这里使用的是 Redis。 正文 当应用程序要去缓存中读取数据,但是缓存中没有找到该数据,则重新去数据库中获取数据,然后将数据存入缓存中。 还有当我们需要更新或者删除缓存中的数据时候,需要让缓存失效...

Spring MVC-学习笔记(4)数据绑定流程

1、请求数据在到达处理方法前这段时间。 spring MVC还会做请求信息转换、数据转换、数据格式化、数据校验。 2、数据转换 1》ConversionService: Spring类型转换体系的核心接口,在其中定义了一下4个方法: 可以在spring上下文中注册一个ConversionServiceFactoryBean,用以定义一个Conversio...

springboot整合filter

新建一个项目       新建Firstfilter类   Firstfliter.java package com.example.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import j...