session-redis 整合 spring-security 序列化时遇到的坑

添加依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-web</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-security</artifactId>
  8. </dependency>
  9. <dependency>
  10. <groupId>org.springframework.session</groupId>
  11. <artifactId>spring-session-data-redis</artifactId>
  12. </dependency>
  13. <dependency>
  14. <groupId>io.lettuce</groupId>
  15. <artifactId>lettuce-core</artifactId>
  16. </dependency>
  17. <dependency>
  18. <groupId>org.springframework.boot</groupId>
  19. <artifactId>spring-boot-devtools</artifactId>
  20. <scope>runtime</scope>
  21. <optional>true</optional>
  22. </dependency>
  23. <dependency>
  24. <groupId>org.springframework.boot</groupId>
  25. <artifactId>spring-boot-configuration-processor</artifactId>
  26. <optional>true</optional>
  27. </dependency>
  28. <dependency>
  29. <groupId>org.projectlombok</groupId>
  30. <artifactId>lombok</artifactId>
  31. <optional>true</optional>
  32. </dependency>

Spring Security 配置类

  1. @Configuration
  2. public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
  3. @Override
  4. public void configure(AuthenticationManagerBuilder auth) throws Exception {
  5. auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
  6. }
  7. @Override
  8. public void configure(HttpSecurity http) throws Exception {
  9. super.configure(http);
  10. }
  11. @Bean
  12. public UserDetailsService userDetailsService(){
  13. return username -> {
  14. List<GrantedAuthority> authorities =
  15. AuthorityUtils.commaSeparatedStringToAuthorityList("admin");
  16. return new User("user", passwordEncoder().encode("123"), authorities);
  17. };
  18. }
  19. @Bean
  20. public PasswordEncoder passwordEncoder(){
  21. return new BCryptPasswordEncoder();
  22. }
  23. }

redis 配置类

  1. @Configuration
  2. public class RedisConfig {
  3. @Bean
  4. public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
  5. RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
  6. Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
  7. redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
  8. redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
  9. redisTemplate.setKeySerializer(new StringRedisSerializer());
  10. redisTemplate.setHashKeySerializer(new StringRedisSerializer());
  11. redisTemplate.setConnectionFactory(redisConnectionFactory);
  12. redisTemplate.setDefaultSerializer(new StringRedisSerializer());
  13. redisTemplate.afterPropertiesSet();
  14. return redisTemplate;
  15. }
  16. @Bean
  17. RedisSerializer<Object> springSessionDefaultRedisSerializer() {
  18. return new GenericJackson2JsonRedisSerializer();
  19. }
  20. }

controller

  1. @RestController
  2. @Slf4j
  3. public class SessionController {
  4. @GetMapping("/hello")
  5. public String hello(){
  6. return "hello";
  7. }
  8. }

浏览器输入localhost:8080/hello 抛出异常

  1. org.springframework.data.redis.serializer.SerializationException: Could not read JSON: Cannot construct instance of `org.springframework.security.authentication.UsernamePasswordAuthenticationToken` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
  2. at [Source: (byte[])"{"@class":"org.springframework.security.core.context.SecurityContextImpl","authentication":{"@class":"org.springframework.security.authentication.UsernamePasswordAuthenticationToken","authorities":["java.util.Collections$UnmodifiableRandomAccessList",[{"@class":"org.springframework.security.core.authority.SimpleGrantedAuthority","authority":"admin"}]],"details":{"@class":"org.springframework.security.web.authentication.WebAuthenticationDetails","remoteAddress":"0:0:0:0:0:0:0:1","sessionId":"8a0c"[truncated 436 bytes]; line: 1, column: 184] (through reference chain: org.springframework.security.core.context.SecurityContextImpl["authentication"]); nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `org.springframework.security.authentication.UsernamePasswordAuthenticationToken` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
  3. at [Source: (byte[])"{"@class":"org.springframework.security.core.context.SecurityContextImpl","authentication":{"@class":"org.springframework.security.authentication.UsernamePasswordAuthenticationToken","authorities":["java.util.Collections$UnmodifiableRandomAccessList",[{"@class":"org.springframework.security.core.authority.SimpleGrantedAuthority","authority":"admin"}]],"details":{"@class":"org.springframework.security.web.authentication.WebAuthenticationDetails","remoteAddress":"0:0:0:0:0:0:0:1","sessionId":"8a0c"[truncated 436 bytes]; line: 1, column: 184] (through reference chain: org.springframework.security.core.context.SecurityContextImpl["authentication"])
  4. at org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer.deserialize(GenericJackson2JsonRedisSerializer.java:152) ~[spring-data-redis-2.6.0.jar:2.6.0]
  5. at org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer.deserialize(GenericJackson2JsonRedisSerializer.java:130) ~[spring-data-redis-2.6.0.jar:2.6.0]
  6. at org.springframework.data.redis.core.AbstractOperations.deserializeHashValue(AbstractOperations.java:380) ~[spring-data-redis-2.6.0.jar:2.6.0]
  7. at org.springframework.data.redis.core.AbstractOperations.deserializeHashMap(AbstractOperations.java:324) ~[spring-data-redis-2.6.0.jar:2.6.0]
  8. at org.springframework.data.redis.core.DefaultHashOperations.entries(DefaultHashOperations.java:309) ~[spring-data-redis-2.6.0.jar:2.6.0]
  9. at org.springframework.data.redis.core.DefaultBoundHashOperations.entries(DefaultBoundHashOperations.java:223) ~[spring-data-redis-2.6.0.jar:2.6.0]
  10. at org.springframework.session.data.redis.RedisIndexedSessionRepository.getSession(RedisIndexedSessionRepository.java:457) ~[spring-session-data-redis-2.6.0.jar:2.6.0]
  11. at org.springframework.session.data.redis.RedisIndexedSessionRepository.findById(RedisIndexedSessionRepository.java:429) ~[spring-session-data-redis-2.6.0.jar:2.6.0]
  12. at org.springframework.session.data.redis.RedisIndexedSessionRepository.findById(RedisIndexedSessionRepository.java:251) ~[spring-session-data-redis-2.6.0.jar:2.6.0]
  13. at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getRequestedSession(SessionRepositoryFilter.java:356) ~[spring-session-core-2.6.0.jar:2.6.0]
  14. at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getSession(SessionRepositoryFilter.java:290) ~[spring-session-core-2.6.0.jar:2.6.0]
  15. at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getSession(SessionRepositoryFilter.java:193) ~[spring-session-core-2.6.0.jar:2.6.0]
  16. at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:244) ~[tomcat-embed-core-9.0.55.jar:4.0.FR]
  17. at org.springframework.security.web.context.HttpSessionSecurityContextRepository.loadContext(HttpSessionSecurityContextRepository.java:118) ~[spring-security-web-5.6.0.jar:5.6.0]
  18. at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:98) ~[spring-security-web-5.6.0.jar:5.6.0]
  19. at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80) ~[spring-security-web-5.6.0.jar:5.6.0]
  20. at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.0.jar:5.6.0]
  21. at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55) ~[spring-security-web-5.6.0.jar:5.6.0]
  22. at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.13.jar:5.3.13]
  23. at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.0.jar:5.6.0]
  24. at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211) ~[spring-security-web-5.6.0.jar:5.6.0]
  25. at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183) ~[spring-security-web-5.6.0.jar:5.6.0]
  26. at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358) ~[spring-web-5.3.13.jar:5.3.13]
  27. at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271) ~[spring-web-5.3.13.jar:5.3.13]
  28. at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  29. at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  30. at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.13.jar:5.3.13]
  31. at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.13.jar:5.3.13]
  32. at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  33. at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  34. at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.13.jar:5.3.13]
  35. at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.13.jar:5.3.13]
  36. at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  37. at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  38. at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:142) ~[spring-session-core-2.6.0.jar:2.6.0]
  39. at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:82) ~[spring-session-core-2.6.0.jar:2.6.0]
  40. at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  41. at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  42. at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.13.jar:5.3.13]
  43. at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.13.jar:5.3.13]
  44. at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  45. at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  46. at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  47. at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  48. at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  49. at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  50. at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  51. at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  52. at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  53. at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  54. at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  55. at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  56. at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1722) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  57. at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  58. at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  59. at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  60. at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  61. at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]

错误原因

有一些类在反序列化时找不到无参构造方法

解决办法

spring 为解决这个错误 ,添加了许多Mixin 类,需要讲这些Mixin类添加到 ObjectMapper中

修改redis配置类

  1. @Configuration
  2. public class RedisConfig {
  3. @Bean
  4. public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
  5. RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
  6. Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
  7. redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
  8. redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
  9. redisTemplate.setKeySerializer(new StringRedisSerializer());
  10. redisTemplate.setHashKeySerializer(new StringRedisSerializer());
  11. redisTemplate.setConnectionFactory(redisConnectionFactory);
  12. redisTemplate.setDefaultSerializer(new StringRedisSerializer());
  13. redisTemplate.afterPropertiesSet();
  14. return redisTemplate;
  15. }
  16. @Bean
  17. RedisSerializer<Object> springSessionDefaultRedisSerializer() {
  18. // 为 ObjectMapper 注册 SecurityJackson2Modules 可以解决 反序列化错误
  19. ObjectMapper mapper = new ObjectMapper();
  20. mapper.registerModules(SecurityJackson2Modules.getModules(this.getClass().getClassLoader()));
  21. return new GenericJackson2JsonRedisSerializer(mapper);
  22. }
  23. }

扩展

如何我们需要将自己定义的bean也通过session - redis 保存,则会报错

修改controller

  1. @RestController
  2. @Slf4j
  3. public class SessionController {
  4. @GetMapping("/session")
  5. public User user(HttpServletRequest request){
  6. User user = new User("user", "123456");
  7. request.getSession().setAttribute("user",user);
  8. log.info("{}", user);
  9. return user;
  10. }
  11. @GetMapping("/getUser")
  12. public User getUser(HttpServletRequest request){
  13. User user = (User) request.getSession().getAttribute("user");
  14. log.info("{}", user);
  15. return user;
  16. }
  17. @GetMapping("/hello")
  18. public String hello(){
  19. return "hello";
  20. }
  21. }

添加bean

  1. @Data
  2. @AllArgsConstructor
  3. @NoArgsConstructor
  4. public class User implements Serializable {
  5. private String name;
  6. private String password;
  7. }

浏览器输入localhost:8080/hello 跳到登录页面

输入正确的账号后,浏览器显示 hello

然后浏览器输入localhost:8080/session报错

  1. org.springframework.data.redis.serializer.SerializationException: Could not read JSON: The class with com.itao.security.bean.User and name of com.itao.security.bean.User is not in the allowlist. If you believe this class is safe to deserialize, please provide an explicit mapping using Jackson annotations or by providing a Mixin. If the serialization is only done by a trusted source, you can also enable default typing. See https://github.com/spring-projects/spring-security/issues/4370 for details; nested exception is java.lang.IllegalArgumentException: The class with com.itao.security.bean.User and name of com.itao.security.bean.User is not in the allowlist. If you believe this class is safe to deserialize, please provide an explicit mapping using Jackson annotations or by providing a Mixin. If the serialization is only done by a trusted source, you can also enable default typing. See https://github.com/spring-projects/spring-security/issues/4370 for details
  2. at org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer.deserialize(GenericJackson2JsonRedisSerializer.java:152) ~[spring-data-redis-2.6.0.jar:2.6.0]
  3. at org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer.deserialize(GenericJackson2JsonRedisSerializer.java:130) ~[spring-data-redis-2.6.0.jar:2.6.0]
  4. at org.springframework.data.redis.core.AbstractOperations.deserializeHashValue(AbstractOperations.java:380) ~[spring-data-redis-2.6.0.jar:2.6.0]
  5. at org.springframework.data.redis.core.AbstractOperations.deserializeHashMap(AbstractOperations.java:324) ~[spring-data-redis-2.6.0.jar:2.6.0]
  6. at org.springframework.data.redis.core.DefaultHashOperations.entries(DefaultHashOperations.java:309) ~[spring-data-redis-2.6.0.jar:2.6.0]
  7. at org.springframework.data.redis.core.DefaultBoundHashOperations.entries(DefaultBoundHashOperations.java:223) ~[spring-data-redis-2.6.0.jar:2.6.0]
  8. at org.springframework.session.data.redis.RedisIndexedSessionRepository.getSession(RedisIndexedSessionRepository.java:457) ~[spring-session-data-redis-2.6.0.jar:2.6.0]
  9. at org.springframework.session.data.redis.RedisIndexedSessionRepository.findById(RedisIndexedSessionRepository.java:429) ~[spring-session-data-redis-2.6.0.jar:2.6.0]
  10. at org.springframework.session.data.redis.RedisIndexedSessionRepository.findById(RedisIndexedSessionRepository.java:251) ~[spring-session-data-redis-2.6.0.jar:2.6.0]
  11. at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getRequestedSession(SessionRepositoryFilter.java:356) ~[spring-session-core-2.6.0.jar:2.6.0]
  12. at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getRequestedSessionId(SessionRepositoryFilter.java:338) ~[spring-session-core-2.6.0.jar:2.6.0]
  13. at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.commitSession(SessionRepositoryFilter.java:228) ~[spring-session-core-2.6.0.jar:2.6.0]
  14. at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.access$100(SessionRepositoryFilter.java:193) ~[spring-session-core-2.6.0.jar:2.6.0]
  15. at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:145) ~[spring-session-core-2.6.0.jar:2.6.0]
  16. at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:82) ~[spring-session-core-2.6.0.jar:2.6.0]
  17. at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  18. at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  19. at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.13.jar:5.3.13]
  20. at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.13.jar:5.3.13]
  21. at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  22. at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  23. at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  24. at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  25. at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  26. at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  27. at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  28. at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  29. at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  30. at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  31. at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  32. at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  33. at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1722) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  34. at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  35. at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  36. at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  37. at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.55.jar:9.0.55]
  38. at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]

报错原因

在redis序列化时加入了

  1. ObjectMapper mapper = new ObjectMapper();
  2. mapper.registerModules(SecurityJackson2Modules.getModules(this.getClass().getClassLoader()));

导致Jacksjson 认为普通bean 是不安全的

解决办法

可以根据仿照spring提供的Mixin类,编写自己的Mixin类

或者在bean的类上添加注解@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)

  1. /**
  2. * If you believe this class is safe to deserialize,
  3. * please provide an explicit mapping using Jackson annotations or by providing a Mixin.
  4. * If the serialization is only done by a trusted source, you can also enable default typing
  5. */
  6. @Data
  7. @AllArgsConstructor
  8. @NoArgsConstructor
  9. @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) // 解决反序列化问题
  10. public class User implements Serializable {
  11. private String name;
  12. private String password;
  13. }

问题解决