zoukankan      html  css  js  c++  java
  • Spring-session redis 子域名 session

    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 id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
    </bean>

    <!-- 设置Cookie domain 和 名称 -->
    <bean id="defaultCookieSerializer" 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 id="redisTemplate" 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"),获取到参数后转码
    ---------------------

  • 相关阅读:
    DateTimePicker控件在WinXP下的BUG
    SmartAssembly .net混淆后,无法找到部分类型
    RPC_E_SERVERFAULT excel com操作错误
    System.Reflection.ReflectionTypeLoadException
    login SMTP send mail error : Unable to read data from the transport connection: net_io_connectionclosed
    静态类无法实现接口
    Combobox出现System.Data.DataRowView的原因
    .net 4.0 : Missing compiler required member 'Microsoft.CSharp.RuntimeBinder.Binder.****'
    EOS 主节点同步
    使用tcpdump抓取EOS帐户创建与交易数据
  • 原文地址:https://www.cnblogs.com/jtlgb/p/9951167.html
Copyright © 2011-2022 走看看