zoukankan      html  css  js  c++  java
  • SpringBoot 集成 Spring Session

    SpringBoot 集成 Spring Session

    应该讲解清楚,为什么要使用 Redis 进行 Session 的管理。

    Session 复制又是什么概念。

    Spring Session 在汪云飞老师的书里的介绍是:

    Spring Session:提供一个 API 及实现来管理用户会话信息。

    我们可以这样理解,原来在 Tomcat 服务器中存在的 Session 统一放置在 Redis 中进行管理。
    这样在服务器集群的时候,就不会出现状态不一致的情况。(这一步还须要描述详细一些,最好把自己实验的过程展示一下)。

    第 1 步:添加依赖

    除了 SpringBoot 最最基础的依赖 spring-boot-starter-web

    compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '1.5.2.RELEASE'
    

    以外,我们还须要添加 spring-boot-starter-data-redisspring-session

    compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-redis', version: '1.5.2.RELEASE'
    compile group: 'org.springframework.session', name: 'spring-session', version: '1.3.0.RELEASE'
    

    另外,我们还须要 Redis 服务的支持。

    第 2 步:添加 Spring Session 相关的配置

    1. 配置 Spring Session 使用 Redis 来进行统一管理,以及 Redis 的主机和端口号
    spring.session.store-type=redis
    
    spring.redis.host=localhost
    spring.redis.port=6388
    
    1. 配置 Session 失效的时间
    @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 24 * 60 * 60)
    public class SessionConfig {
    }
    

    下面编写测试代码。

    @RestController
    public class SessionController {
    
        // 用于测试 SpringBoot 容器是否启动
        // http:localhost:8080/test
        @RequestMapping("/test")
        public String test(){
            return "PING OK";
        }
    
        // http:localhost:8080/put?key=name&value=liwei
        @RequestMapping("/put")
        public String put(HttpSession session,
                          @RequestParam("key") String key,@RequestParam("value") String value){
            session.setAttribute(key,value);
            return "PUT OK";
        }
    
        // http:localhost:8080/get?key=name
        @RequestMapping("/get")
        public String get(HttpSession session,
                          @RequestParam("key") String key){
            String value = (String) session.getAttribute(key);
    
            if(value == null || "".equals(value)){
                return "NO VALUE GET";
            }
            return value;
        }
    
    }
    

    我们执行

    gradle clean build
    

    然后再执行

    java -jar build/libs/SpringBootSessionDemo-1.0-SNAPSHOT.jar --server.port=8081
    java -jar build/libs/SpringBootSessionDemo-1.0-SNAPSHOT.jar --server.port=8082
    java -jar build/libs/SpringBootSessionDemo-1.0-SNAPSHOT.jar --server.port=8083
    

    启动 3 台服务器。

    实验的思路是这样的:在 1 台服务器上的 Session 中放入 key 和 value,在另外两台服务器上都可以获得 key 对应的 value。

    第 1 步:请求
    http://localhost:8081/put?key=age&value=24

    第 2 步:
    http://localhost:8082/get?key=age
    http://localhost:8083/get?key=age
    此时,在两台服务器 8082 和 8083 上可以看到我们在服务器 8081 的 Session 中放入的数据。

    第 3 步:登录 Redis 服务端,情况 Redis 的缓存,再次执行第 2 步的请求,发现不能获得 Session 的数据。

    redis-cli -p 6388
    flushdb
    

    至此,就说明此时 3 台服务器上的 Session 都由 Redis 来管理了。
    如果我们把关于 Spring Session 和 Redis 的配置都去掉的话,就会发现在 1 台服务器上的 Session 的设置和获取都只能在这台服务器上完成。

    补充说明:在 Gradle 项目中要通过使用 spring-boot 这个插件,才能使打出来的 jar 包可以执行 java -jar 开始运行。
    配置方法:

    allprojects {
        repositories {
            maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
        }
    }
    
    buildscript {
    
        ext {
            springBootVersion = '1.5.2.RELEASE'
        }
    
        repositories {
            jcenter()
            mavenLocal()
            mavenCentral()
            maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
            maven { url "http://repo.spring.io/release" }
            maven { url "http://repo.spring.io/milestone" }
            maven { url "http://repo.spring.io/snapshot" }
        }
        dependencies {
            classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"
            classpath "com.github.adrianbk:gradle-jvmsrc-plugin:0.6.1"
        }
    }
    

    此时,就可以使用 spring-boot 插件了。

    apply plugin: 'spring-boot'
    
    org.springframework.data.redis.serializer.SerializationException: Cannot serialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [com.liwei.model.User]
            at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize(JdkSerializationRedisSerializer.java:93) ~[spring-data-redis-1.8.1.RELEASE.jar!/:na]
            at org.springframework.data.redis.core.AbstractOperations.rawHashValue(AbstractOperations.java:171) ~[spring-data-redis-1.8.1.RELEASE.jar!/:na]
            at org.springframework.data.redis.core.DefaultHashOperations.putAll(DefaultHashOperations.java:129) ~[spring-data-redis-1.8.1.RELEASE.jar!/:na]
            at org.springframework.data.redis.core.DefaultBoundHashOperations.putAll(DefaultBoundHashOperations.java:86) ~[spring-data-redis-1.8.1.RELEASE.jar!/:na]
            at org.springframework.session.data.redis.RedisOperationsSessionRepository$RedisSession.saveDelta(RedisOperationsSessionRepository.java:778) ~[spring-session-1.3.0.RELEASE.jar!/:na]
            at org.springframework.session.data.redis.RedisOperationsSessionRepository$RedisSession.access$000(RedisOperationsSessionRepository.java:670) ~[spring-session-1.3.0.RELEASE.jar!/:na]
            at org.springframework.session.data.redis.RedisOperationsSessionRepository.save(RedisOperationsSessionRepository.java:388) ~[spring-session-1.3.0.RELEASE.jar!/:na]
            at org.springframework.session.data.redis.RedisOperationsSessionRepository.save(RedisOperationsSessionRepository.java:245) ~[spring-session-1.3.0.RELEASE.jar!/:na]
            at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.commitSession(SessionRepositoryFilter.java:245) ~[spring-session-1.3.0.RELEASE.jar!/:na]
            at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.access$100(SessionRepositoryFilter.java:217) ~[spring-session-1.3.0.RELEASE.jar!/:na]
            at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:170) ~[spring-session-1.3.0.RELEASE.jar!/:na]
            at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:80) ~[spring-session-1.3.0.RELEASE.jar!/:na]
            at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.11.jar!/:8.5.11]
            at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.11.jar!/:8.5.11]
            at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
            at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
            at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.11.jar!/:8.5.11]
            at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.11.jar!/:8.5.11]
            at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) ~[tomcat-embed-core-8.5.11.jar!/:8.5.11]
            at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
            at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:474) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
            at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
            at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
            at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
            at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
            at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:783) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
            at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
            at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:798) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
            at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1434) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
            at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_45]
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_45]
            at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
            at java.lang.Thread.run(Thread.java:745) [na:1.8.0_45]
    Caused by: org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [com.liwei.model.User]
            at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:68) ~[spring-core-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
            at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:35) ~[spring-core-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
            at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize(JdkSerializationRedisSerializer.java:91) ~[spring-data-redis-1.8.1.RELEASE.jar!/:na]
            ... 33 common frames omitted
    Caused by: java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [com.liwei.model.User]
            at org.springframework.core.serializer.DefaultSerializer.serialize(DefaultSerializer.java:43) ~[spring-core-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
            at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:63) ~[spring-core-4.3.7.RELEASE.jar!/:4.3.7.RELEASE]
            ... 35 common frames omitted
    

    User 类要实现序列化接口。
    http://localhost:8081/put/user
    http://localhost:8082/put/user
    http://localhost:8083/put/user

    这篇文章涉及到的源代码可以在我的 GitHub 上下载:https://github.com/weimingge14/SpringBootSessionDemo

  • 相关阅读:
    EXE中释放文件
    关闭GS选项,解决注入后崩溃
    HDU2516 取石子游戏
    HDU2188 选拔志愿者
    HDU2149 Public Sale
    HDU2147 kiki's game
    HDU1846 Brave Game
    LightOJ1214 Large Division
    POJ2480 Longge's problem
    HDU 5880 Family View
  • 原文地址:https://www.cnblogs.com/liweiwei1419/p/6794241.html
Copyright © 2011-2022 走看看