在做项目的时候,需要对发票的数据进行一个缓存,在redis中是想以json的数据进行存储。但是在取数据的时候会报错:
org.springframework.data.redis.serializer.SerializationException: Could not read JSON: Unexpected token (END_OBJECT), expected FIELD_NAME: missing property '@class' that is to contain type id (for class java.lang.Object)
at [Source: [B@4649d70a; line: 1, column: 5611]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Unexpected token (END_OBJECT), expected FIELD_NAME: missing property '@class' that is to contain type id (for class java.lang.Object)
at [Source: [B@4649d70a; line: 1, column: 5611]
大概意思就是,redis的序列化错误,就是说这个id类型的属性丢失,映射错误。
现在看一下我们的redis中的数据是什么样的:注意这里的属性,属性的位置的顺序不对。
这是我的属性的顺序,请和上面的json的数据进行对比一下:应该发现问题了吧?上面的json的数据还没有全部截取完毕,但是主要的问题就是属性顺序颠倒了!这里的这个@JSONFiled注解是我测试阿里的fastjson设置的,可以忽略,在实际的开发中可以忽略这个!
因此:使用GenericJackson2JsonRedisSerializer作为redis的序列化json确实会存在一些隐藏的问题!
解决的办法:使用阿里巴巴的fastjson作为redis的序列化工具即可!
主要配置如下,我是直接配置到了代码中!
package com.ilongsay.redisConfig; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.StringRedisSerializer; /** * @Author ilongsay * @Email ilongsay@163.com * @Copyright 版本所有,侵权必究! * @Datetime 2019-02-25 22:58 * @Describution */ @Configuration @EnableCaching public class RedisConfig extends CachingConfigurerSupport { @Autowired private JedisConnectionFactory jedisConnectionFactory; @Autowired private RedisTemplate<Object,Object> redisTemplate; /** * @param connectionFactory 这个报错不影响使用 * @return org.springframework.data.redis.core.RedisTemplate<java.lang.Object,java.lang.Object> * */ @Bean(name = "redisTemplate") public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) { connectionFactory = jedisConnectionFactory; RedisTemplate<Object, Object> template = new RedisTemplate<>(); template.setConnectionFactory(connectionFactory); //使用Fastjson2JsonRedisSerializer序列化value的值 FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class); ObjectMapper mapper = new ObjectMapper(); mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); serializer.setObjectMapper(mapper); template.setValueSerializer(serializer); //使用StringRedisSerializer序列化redis的key值 template.setKeySerializer(new StringRedisSerializer()); template.afterPropertiesSet(); return template; } }
再运行一遍获取的value的值,完美获取映射不报错,美滋滋