【问题标题】:Unable to deserialize Spring Session Scoped bean无法反序列化 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 注解?

标签: java spring spring-mvc session


【解决方案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也不知道会话。

    我知道这可以帮助您更改实施策略以找到问题的解决方案

    【讨论】:

      猜你喜欢
      • 2014-01-04
      • 2017-02-15
      • 2012-04-09
      • 1970-01-01
      • 2015-03-30
      • 1970-01-01
      • 1970-01-01
      • 2015-11-14
      • 2017-05-24
      相关资源
      最近更新 更多