V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kytrun
V2EX  ›  Java

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

  •  
  •   kytrun ·
    kytrun · 104 天前 · 1411 次点击
    这是一个创建于 104 天前的主题,其中的信息可能已经有所发展或是发生改变。

    从 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 版本一直不升级。

    9 条回复    2022-11-21 19:51:37 +08:00
    zhouhu
        1
    zhouhu  
       104 天前
    redis 历史数据没做兼容吧?
    ql562482472
        2
    ql562482472  
       104 天前
    jackson 少了个配置把应该是
    字段带属性那种序列化应该是要 objectmapper enable NON_FINAL 和 jsonTypeInfo.As.PROPERTY
    L0L
        3
    L0L  
       104 天前
    感觉像是 jackson 可能多了一些默认配置?可以写个 demo 试一试?
    OldCarMan
        4
    OldCarMan  
       104 天前
    话说,为啥
    "accountId": [
    "java.lang.Long",
    25
    ]
    kytrun
        5
    kytrun  
    OP
       104 天前
    @OldCarMan 就是一个对象里有个 Long 类型的字段,我也不知道为什么之前的版本把类型和值是存到一个 Array 里的,可能后来默认的简化了
    corningsun
        6
    corningsun  
       104 天前
    项目里面还有别的地方配置 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
        7
    OldCarMan  
       104 天前
    @kytrun 将 JsonTypeInfo.As.PROPERTY 换成 JsonTypeInfo.As WRAPPER_ARRAY 试试?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   实用小工具   ·   3720 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 47ms · UTC 02:57 · PVG 10:57 · LAX 18:57 · JFK 21:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.