Spring Session在Spring MVC中的使用.md

  1. Web项目会通过Session进行会话保持,Session是保存在服务器内存中;
  2. 现在为了提高站点的性能和稳定性,将Web项目发布到多个服务器,通过代理如Nginx或F5做负载均衡;
  3. 由于负载均衡正常配置,会对客户端的请求随机转发到某一个服务器,这会导致Session丢失;
  4. 解决方案:一种是可将代理如Nginx或F5配置为高可用,即用户访问时,在同一会话期间内,只往一台服务器转发;另一种是引入Spring Session,对Session进行持久化、统一管理;
  5. Spring Session对Session进行了透明封装,可将原本通过Session存在内存的数据,持久化到redis等缓存数据库中,实现Session的持久化和统一管理,且开发人员只要引入Spring Session,使用时依旧跟平时用Session操作时一样;

官方文档:https://spring.io/projects/spring-session

以下记录Spring MVC中采用Spring Session+redis的实现方案。

第一步:pom配置引入依赖包

        <!-- spring session依赖包 -->
        <!-- Spring Data Redis -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
            <version>1.7.3.RELEASE</version>
        </dependency>
        <!-- Spring Session -->
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session</artifactId>
            <version>1.2.2.RELEASE</version>
        </dependency>
        <!-- Apache Commons Pool -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.4.2</version>
        </dependency>

第二步:配置spring-mvc.xml:

    <!-- 通过配置文件扫描获取详细的配置信息 -->
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:app.properties"/>
    </bean>

    <!--新增spring-session配置-->
    <bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"/>
    <!--<bean class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">-->
        <!--<property name="hostName" value="localhost" />-->
        <!--<property name="password" value="your-password" />-->
        <!--<property name="port" value="6379" />-->
        <!--<property name="database" value="10" />-->
    <!--</bean>-->
    <!--JedisConnectionFactory -->
    <bean class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <constructor-arg index="0">
            <bean class="org.springframework.data.redis.connection.RedisClusterConfiguration">
                <constructor-arg index="0">
                    <set>
                        <value>${REDIS.CLUSTERS}</value>
                    </set>
                </constructor-arg>
                <property name="maxRedirects" value="5" />
            </bean>
        </constructor-arg>
        <constructor-arg index="1">
            <!-- redis缓存配置 -->
            <bean class="redis.clients.jedis.JedisPoolConfig">
                <property name="maxIdle" value="6000" /><!-- 最大空闲时间 -->
                <property name="maxWaitMillis" value="1500"/><!-- 获得链接时的最大等待毫秒数,小于0:阻塞不确定时间,默认-1 -->
                <property name="testOnBorrow" value="true" /><!-- 在获得链接的时候检查有效性,默认false -->
                <property name="testOnReturn" value="true" />
            </bean>
        </constructor-arg>
    </bean>
    <!-- 让Spring Session不再执行config命令 -->
    <util:constant static-field="org.springframework.session.data.redis.config.ConfigureRedisAction.NO_OP"/>

第三步:配置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>

碰到问题

报错:

org.springframework.data.redis.serializer.SerializationException: Cannot serialize;

解决方案:
要缓存的JavaBean需要实现Serializable接口,因为Spring会将对象先序列化再存入Redis,针对于此异常,修改对应的JavaBean对象即可,实现Serializable:

public class SessionUser implements Serializable {
}

PS:所以session所调用的JavaBean对象都要实现Serializable,否则反序列化就会出错;

猜你喜欢

转载自blog.csdn.net/cwp5757/article/details/81207797