• 请不要在回答技术问题时复制粘贴 AI 生成的内容
JasonLaw
V2EX  ›  程序员

GenericJackson2JsonRedisSerializer 序列化会存在多余的双引号,怎么解决?

  •  
  •   JasonLaw · Dec 1, 2021 · 1686 views
    This topic created in 1660 days ago, the information mentioned may be changed or developed.

    RedisTemplate 如下:

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(connectionFactory);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        ObjectMapper objectMapper = new ObjectMapper();
        PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder()
                                                                    .allowIfSubType(Object.class)
                                                                    .build();
        objectMapper.activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.NON_FINAL);
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer(objectMapper));
        return redisTemplate;
    }
    

    执行以下代码后

    redisTemplate.opsForValue()
                 .set("k", "v");
    

    get k 的结果如下,会有多余的双引号,要怎么解决呢?只能使用 StringRedisSerializer 吗?

    Supplement 1  ·  Dec 7, 2021

    通过extends GenericJackson2JsonRedisSerializer,然后redisTemplate.setValueSerializer(new CustomGenericJackson2JsonRedisSerializer());解决了这个问题。

    class CustomGenericJackson2JsonRedisSerializer extends GenericJackson2JsonRedisSerializer {
    
        private static final ObjectMapper OBJECT_MAPPER;
    
        static {
            OBJECT_MAPPER = new ObjectMapper().registerModule(new JavaTimeModule());
            // https://github.com/FasterXML/jackson-docs/wiki/JacksonPolymorphicDeserialization
            PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder()
                                                                        .allowIfSubType(Object.class)
                                                                        .build();
            OBJECT_MAPPER.activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
        }
    
        public CustomGenericJackson2JsonRedisSerializer() {
            super(OBJECT_MAPPER);
        }
    
        @Override
        public byte[] serialize(Object source) throws SerializationException {
            if (source instanceof String) {
                return ((String) source).getBytes(StandardCharsets.UTF_8);
            } else {
                return super.serialize(source);
            }
        }
    }
    
    5 replies    2021-12-07 21:55:31 +08:00
    chendy
        1
    chendy  
       Dec 1, 2021
    json 里的字符串带引号
    所以按照 json 格式序列化字符串也带引号
    只要字符串的话 StringRedisSerializer 就够用了
    JasonLaw
        2
    JasonLaw  
    OP
       Dec 1, 2021 via iPhone
    @chendy #1 代码里面执行系列化和反序列化?相当于使用 RedisTemplate<String, String>,而不是 RedisTemplate<String, Object>?
    billly
        3
    billly  
       Dec 2, 2021
    json 就是这样的啊,只要它能正确反序列化,也没什么问题吧
    gadfly3173
        4
    gadfly3173  
       Dec 2, 2021
    这个算是 GenericJackson2JsonRedisSerializer 的缺陷,也可以说是妥协。因为这个序列化类是用来处理 json 的,也就是[]{}之类的,突然冒出来个无法识别的东西,又不知道它是不是真的是字符串,所以使用双引号来表示这个值确实是字符串。觉得这样不能接受的话,就在你能确定结果一定是字符串的地方用 StringRedisTemplate 就行了。
    JasonLaw
        5
    JasonLaw  
    OP
       Dec 7, 2021
    @chendy #1
    @billly #3
    @gadfly3173 #4

    我通过 extends GenericJackson2JsonRedisSerializer ,然后 redisTemplate.setValueSerializer(new CustomGenericJackson2JsonRedisSerializer());解决了这个问题。详细见附言。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2579 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 60ms · UTC 09:38 · PVG 17:38 · LAX 02:38 · JFK 05:38
    ♥ Do have faith in what you're doing.