Spring会话,部署后从“本地类不兼容”恢复

问题描述 投票:0回答:1

Spring会话将序列化对象存储在我的数据库中。问题是,有时我的代码会发生变化。有时我的对象会改变。这个是正常的。但是,我得到这样的错误:

org.springframework.core.convert.ConversionFailedException: Failed to convert from type [byte[]] to type [java.lang.Object] for value '{-84, ..., 112}'; 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: com.mysite.MyClass; local class incompatible: stream classdesc serialVersionUID = 1432849980928799324, local class serialVersionUID = 8454085305026634675

我通过使用HttpSession作为参数调用Spring Boot端点来获取此错误,例如:

@GetMapping("/stuff")
public @ResponseBody MyClass getStuff(HttpSession session) {
    try {
        Object myObject = session.getAttribute("MyClass");
        if (myObject != null && myObject instanceof MyClass) {
            return (MyClass) myObject;
        } else {
            return null;
        }
    } catch (Exception e) {
        logger.warn("Invalid session data", e);
        return null;
    }
}

但是,因为在调用方法之前抛出异常,我无法从此正常的预期错误中恢复。

作为一种解决方法,我被迫删除每个部署的整个会话表,即使大多数对象仍然兼容!

要清楚,解决方案是不添加serialVersionUuid。因为对象确实以不兼容的方式从一个部署更改为下一个部署。这不是序列化问题。这是一个Spring Session错误恢复问题。

我的问题是:我如何从这些问题中优雅地恢复?

java spring spring-session
1个回答
0
投票

您没有提供详细信息,但我假设您正在使用@EnableJdbcHttpSession启用的Spring的JDBC会话实现?

在这种情况下,你可以看看JdbcHttpSessionConfiguration,特别是在setSpringSessionConversionServicesetConversionService。我相信如果您提供自己的实现(您可以在createConversionServiceWithBeanClassLoader上看到示例),那么您应该能够捕获反序列化错误并返回空会话。

我认为你需要的是从MyNotFailingSessionDeserializer派生DeserializingConverter,覆盖convert方法,捕捉SerializationFailedException并返回null或空会话(不确定是否有效)。

然后你创建你的转换服务,如createConversionServiceWithBeanClassLoader,但使用你的MyNotFailingSessionDeserializer而不是DeserializingConverter

© www.soinside.com 2019 - 2024. All rights reserved.