升级 Spring Boot 版本导致 jackson 序列化形式不一致的疑问

2022-10-21 11:53:01 +08:00
 kytrun

从 Spring Boot 2.7.1 升级到 2.7.5 (问题从 2.7.2 开始), 项目用了 sa-token-dao-redis-jackson,jackson 序列化将对象中的 Long 由原本的

{
...
"accountId": [
                "java.lang.Long",
                25
            ],
...
}

改成了

...
"accountId": 25,
...

数据存到 Redis 的升级之后不兼容,登录报错:

Could not read JSON: Cannot deserialize value of type `java.lang.Long` from Array value (token `JsonToken.START_ARRAY`)

Redis 配置:

    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(connectionFactory);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringRedisSerializer);
        redisTemplate.setHashKeySerializer(stringRedisSerializer);

        Jackson2JsonRedisSerializer<?> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
        SimpleModule simpleModule = new SimpleModule();
        objectMapper.registerModule(simpleModule);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

我想请教,升级版本后能否通过配置保持旧的序列化形式? 如果不行的话就只能清除缓存强行升级了,所有的用户登录状态会丢失,或者…… 停在 2.7.1 版本一直不升级。

2176 次点击
所在节点    Java
9 条回复
zhouhu
2022-10-21 12:13:47 +08:00
redis 历史数据没做兼容吧?
ql562482472
2022-10-21 12:15:02 +08:00
jackson 少了个配置把应该是
字段带属性那种序列化应该是要 objectmapper enable NON_FINAL 和 jsonTypeInfo.As.PROPERTY
L0L
2022-10-21 14:20:34 +08:00
感觉像是 jackson 可能多了一些默认配置?可以写个 demo 试一试?
OldCarMan
2022-10-21 14:35:51 +08:00
话说,为啥
"accountId": [
"java.lang.Long",
25
]
kytrun
2022-10-21 15:00:37 +08:00
@OldCarMan 就是一个对象里有个 Long 类型的字段,我也不知道为什么之前的版本把类型和值是存到一个 Array 里的,可能后来默认的简化了
corningsun
2022-10-21 17:16:41 +08:00
项目里面还有别的地方配置 ObjectMapper Bean 吗? 可能序列化配置不统一导致的。

@Bean
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
SimpleModule simpleModule = new SimpleModule();
objectMapper.registerModule(simpleModule);
return objectMapper;
}
OldCarMan
2022-10-21 17:24:12 +08:00
@kytrun 将 JsonTypeInfo.As.PROPERTY 换成 JsonTypeInfo.As WRAPPER_ARRAY 试试?
Oktfolio
2022-11-16 13:32:46 +08:00
kytrun
2022-11-21 19:51:37 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/888675

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX