如何捕获 redis.serializer.SerializationException [英] How to catch redis.serializer.SerializationException

查看:105
本文介绍了如何捕获 redis.serializer.SerializationException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Spring 框架 (4.1.6) 上有应用程序,使用 Spring Security 4.0.1.我在应用程序中使用 @EnableRedisHttpSession 和 @EnableSpringHttpSession,一切正常.但是在将 Spring Security 版本升级到 4.2.1 后,我在新包上的序列化旧版本出现问题.

I have application on Spring framework(4.1.6), using Spring Security 4.0.1. I'm use @EnableRedisHttpSession and @EnableSpringHttpSession in application, and all work fine. But after upgrade version of Spring Security to 4.2.1 i have a problem with Serialization old version on new package.

我的堆栈跟踪是:

org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [dispatcher] in context with path [] threw exception
 org.springframework.data.redis.serializer.SerializationException: Cannot deserialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is java.io.InvalidClassException: org.springframework.security.core.context.SecurityContextImpl; local class incompatible: stream classdesc serialVersionUID = 400, local class serialVersionUID = 420
    at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.deserialize(JdkSerializationRedisSerializer.java:41)
    at org.springframework.data.redis.core.AbstractOperations.deserializeHashValue(AbstractOperations.java:316)
    at org.springframework.data.redis.core.AbstractOperations.deserializeHashMap(AbstractOperations.java:277)
    at org.springframework.data.redis.core.DefaultHashOperations.entries(DefaultHashOperations.java:227)
    at org.springframework.data.redis.core.DefaultBoundHashOperations.entries(DefaultBoundHashOperations.java:101)
    at org.springframework.session.data.redis.RedisOperationsSessionRepository.getSession(RedisOperationsSessionRepository.java:421)
    at org.springframework.session.data.redis.RedisOperationsSessionRepository.getSession(RedisOperationsSessionRepository.java:392)
    at org.springframework.session.data.redis.RedisOperationsSessionRepository.getSession(RedisOperationsSessionRepository.java:252)
    at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getSession(SessionRepositoryFilter.java:270)
    at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getSession(SessionRepositoryFilter.java:286)
    at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.getSession(SessionRepositoryFilter.java:170)
    at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:231)
    at org.springframework.security.web.context.HttpSessionSecurityContextRepository.loadContext(HttpSessionSecurityContextRepository.java:110)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:100)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:126)
    at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:65)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:783)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:798)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1441)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is java.io.InvalidClassException: org.springframework.security.core.context.SecurityContextImpl; local class incompatible: stream classdesc serialVersionUID = 400, local class serialVersionUID = 420
    at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:78)
    at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:36)
    at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.deserialize(JdkSerializationRedisSerializer.java:39)
    ... 53 more

我不明白,如何在 Spring 中捕获此异常.

I don't understand, how to catch this exception inside Spring.

我的问题是:如何捕捉这个异常,进一步显示一个简单的错误页面?".

My question is:" How to catch this exception, to further display a simple error page?".

附言我无法清理旧会话.任何帮助都会很酷!

P.S. I can't clean old sessions. Any help will be cool!

推荐答案

从 Spring Boot 2.3.3、Spring 5.x 开始,Spring Session 仍不支持.

Still not supported by Spring Session as of Spring Boot 2.3.3, Spring 5.x.

也就是说,只要所有应用程序都具有最新版本的 Spring Security,该项目就会停止更新 serialVersionUID 的值以最大程度地减少版本冲突.

That said, as long as all apps have a fairly current version of Spring Security, the project has stopped updating the value of serialVersionUID to minimize version conflicts.

否则,有一些变通方法可以简化转换,或者,如果您愿意做一些工作,可以将 SecurityContext 类序列化为 JSON.

Otherwise, there are a couple work-arounds that can either ease transistions or, if you're willing to do some work, serialize SecurityContext class as JSON.

但是可用的信息是分散的,有时是相互矛盾的.小心踩踏.

But the available information is scattered and sometimes conflicting. Tread carefully.

要点:

更多详情:

  1. Spring Session 上记录了很多与此问题相关的问题.没有人真正完全解决了这个问题.

  1. There are a bunch of issues logged on Spring Session related to this issue. None has actually solved the problem fully.

最简单的解决方法是删除旧"文件.最有可能强制用户再次登录的会话(但是,如果使用了记住我"令牌,则用户可能看不到).

The simplest work-around deletes the "old" sessions which most likely forces the user to log in again (but, if remember me tokens are used, may not be visible to the user).

通过一些更深层次的 Spring Boot 配置黑客攻击,似乎可以以 JSON 格式存储您的 Spring Security 会话.这可能允许运行不同版本 Spring Security 的不同应用共享会话.天啊.

With some deeper Spring Boot configuration hacking, it appears it may be possible to store your Spring Security session in JSON format. This may allow different apps running different versions of Spring Security to share sessions. YMMV.

这篇关于如何捕获 redis.serializer.SerializationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆