为什么Jackson redis serializer启用 USE_LONG_FOR_INTS 不起作用?

我最近才知道Jackson通过开启配置USE_LONG_FOR_INTS可以将整型数据默认转换为Long类型,于是我将我的redisTemplate配置如下:

    @Bean

@SuppressWarnings("all")

public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory)

{

RedisTemplate<String, Object> template = new RedisTemplate<>();

template.setConnectionFactory(connectionFactory);

ObjectMapper objectMapper = new ObjectMapper();

// 开启默认转换Long类型配置

objectMapper.enable(DeserializationFeature.USE_LONG_FOR_INTS);

Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);

jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

template.setKeySerializer(RedisSerializer.string());

template.setHashKeySerializer(RedisSerializer.string());

template.setDefaultSerializer(jackson2JsonRedisSerializer);

return template;

}

但是并没有像我预想的一样:

    @Test

void test() throws JsonProcessingException {

redisTemplate.opsForValue().set("key", 11);

System.out.println(redisTemplate.opsForValue().get("key").getClass());

}

上面测试代码会打印Integer而非Long。

我仔细跟踪了下源码,发现大概是因为反序列化时执行的是这个函数com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer.Vanilla#deserializeWithType,这个函数中并没有判断当前是否开启了USE_LONG_FOR_INTS,只会判断是否开启了USE_BIG_INTEGER_FOR_INTS

我想知道咋样才能让Jackson默认返回Long类型,还是说没有办法了,只能写一个工具类每个取到返回值时自己做类型转换。


回答:

你可以创建一个自定义的反序列化器,然后在反序列化时将整数值转换为 Long 类型。

public class CustomDeserializer extends JsonDeserializer<Object> {

private final UntypedObjectDeserializer delegate;

public CustomDeserializer() {

this.delegate = new UntypedObjectDeserializer(null, null);

}

@Override

public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {

Object value = delegate.deserialize(p, ctxt);

if (value instanceof Integer) {

return ((Integer) value).longValue();

}

return value;

}

}

然后把你创建的自定义反序列化器添加到 Jackson 的配置中:

@Bean

@SuppressWarnings("all")

public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {

RedisTemplate<String, Object> template = new RedisTemplate<>();

template.setConnectionFactory(connectionFactory);

ObjectMapper objectMapper = new ObjectMapper();

objectMapper.registerModule(new SimpleModule().addDeserializer(Object.class, new CustomDeserializer()));

Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);

jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

template.setKeySerializer(RedisSerializer.string());

template.setHashKeySerializer(RedisSerializer.string());

template.setDefaultSerializer(jackson2JsonRedisSerializer);

return template;

}


回答:

我测了下 这样是可以的

@Configuration

public class Redis {

@Resource

private RedisTemplate<String, Object> redisTemplate;

@PostConstruct

public void init() {

ObjectMapper objectMapper = new ObjectMapper();

// 开启默认转换Long类型配置

objectMapper.enable(DeserializationFeature.USE_LONG_FOR_INTS);

Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);

jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);

}

}

以上是 为什么Jackson redis serializer启用 USE_LONG_FOR_INTS 不起作用? 的全部内容, 来源链接: utcz.com/p/945111.html

回到顶部