无法反序列化 Spring Session Scoped bean
Posted
技术标签:
【中文标题】无法反序列化 Spring Session Scoped bean【英文标题】:Unable to deserialize Spring Session Scoped bean 【发布时间】:2016-09-09 19:32:35 【问题描述】:我有以下会话范围的 bean:
@ManagedBean
@Component
@Scope(proxyMode= ScopedProxyMode.TARGET_CLASS, value="session")
public class SessionData implements Serializable
我将 tomcat 会话存储在数据库中。问题是,当应用程序尝试反序列化存储的会话时,我收到以下错误:
org.apache.catalina.session.PersistentManagerBase.swapIn Error deserializing Session EE913D2ACAD49EB55EDA657A54DFA2CB: 1
java.lang.ClassNotFoundException: de.myproject.SessionData$$EnhancerBySpringCGLIB$$768b59b9
似乎它实际上序列化了整个Spring上下文,并且服务器重新启动后显然没有这样的类de.myproject.SessionData$$EnhancerBySpringCGLIB$$768b59b9
,所以我收到了上述异常。
有没有办法避免这种情况,以便会话范围的 bean 被正确序列化?
更新:有一个issue 认为这是在没有 cmets 的情况下已解决,但我仍然面对它。
【问题讨论】:
如何将会话数据存储在数据库中? 我已将 Tomcat 服务器配置为在数据库中存储会话。 困惑:@ManagedBean 是 JSF 注解,为什么你在一个 bean 上同时有 JSF 和 Spring 注解? 【参考方案1】:请试一试:
使用:import org.springframework.test.util.AopTestUtils;
Serializable readyToSerialize = AopTestUtils.getUltimateTargetObject(yourInstance);
在序列化之前。
注意:这段代码对理解问题很有用,如果可以的话,你必须分析项目架构和依赖关系,以便更好地完成生产代码。首先,为什么要序列化一个ScopedProxyMode.TARGET_CLASS
【讨论】:
【参考方案2】:拥有一个具有作用域会话的 bean 并不意味着该 bean 是可序列化的并且可以存储在会话中。
从类的名称可以猜到,在运行时会生成一个代理类,每次启动时使用不同的名称。这就解释了为什么反序列化时会出现问题。
我猜您尝试将此 SessionData 添加为 Web 会话的属性。你不应该。在不使用 bean 的情况下将 POJO 数据存储在 Web 会话中。
如果您使用 bean 注入数据库连接或类似对象,请忘记它。您可以只将会话范围 bean 用于我猜不符合您要求的特定上下文。
【讨论】:
这是 JSF bean,JSF 会自动序列化所有 Session 范围的 bean 并将它们存储在 session 中。【参考方案3】:我不太了解你的任务,但在我看来,这样的数据对象不应该是 spring bean,因为 spring bean 应该是业务逻辑 bean、控制器 bean 等等,而不是会话 dto。
出于这个原因,我认为您应该尝试思考为什么要存储 spring bean 的数据,并尝试从应该的业务逻辑 bean 中解耦 http session 中所需的数据,springmvc 的@sessionattribute也不知道会话。
我知道这可以帮助您更改实施策略以找到问题的解决方案
【讨论】:
以上是关于无法反序列化 Spring Session Scoped bean的主要内容,如果未能解决你的问题,请参考以下文章
spring boot 无法反序列化-HttpMessageNotReadableException
Spring Boot 2 / GraphQL 扩展标量不起作用:异常“无法构造实例”“无法反序列化”