最近学习redis碰到的问题,记录一下
反序列化报错信息:
Request processing failed; nested exception is org.springframework.data.redis.serializer.SerializationException: Could not read JSON: Missing type id when trying to resolve subtype of [simple type, class java.lang.Object]: missing type id property '@class' |
问题:使用redis查询数据的时候反序列化失败,刚开始使用的序列化器Jackson2JsonRedisSerializer,在网上看到大佬说使用这个序列化器做序列化的时候没问题,但是反序列化会报错,于是改成了GenericJackson2JsonRedisSerializer序列化器,问题还是没有得到解决,以下是自定义redis配置文件:
package com.pzy.conf;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
redisTemplate.setDefaultSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
需要向redis存储List<Item>,测试发现通过jedis可以实现序列化和反序列化:
@Test
public void TestAddRedis() {
Jedis jedis = new Jedis("192.168.187.131", 6379);
List<Item> items = new ArrayList<>();
Item item = new Item("2", "Title", "image.jpg", "example.com", 200, true, 10, "shanghai");
// jedis.lpush("hotProduct", items);
JSON json = JSONUtil.parse(item);
String itemStr = JSONUtil.toJsonStr(json);
// jedis.set("hotProduct", null);
// jedis.lpush("hotProduct",itemStr);
// jedis.del("hotProduct");
List<String> hotProduct = jedis.lrange("hotProduct", 0, -1);
System.out.println(hotProduct);
}
返回结果:
说明redis存储的数据没有问题,最后根据报错信息排查发现使用redisTemplate来反序列化数据获取对象,对象需要有默认的空构造方法才可以,加上后问题得到解决。附上对象类:
package com.pzy.pojo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import java.io.Serializable;
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
@JsonIgnoreProperties(ignoreUnknown = true)
public class Item implements Serializable {
private static final long serialVersionUID = -1;
// 主键
private String id;
// 标题
private String title;
// 商品图片
private String img;
// 点击跳转
private String link;
// 销量
private Integer sales;
// 是否为热门
private Boolean recommendation;
// 热门排序
private Integer recoSort;
// 所属城市
private String city;
public Item() {
}
public Item(String id, String title, String img, String link, Integer sales, Boolean recommendation, Integer recoSort, String city) {
this.id = id;
this.title = title;
this.img = img;
this.link = link;
this.sales = sales;
this.recommendation = recommendation;
this.recoSort = recoSort;
this.city = city;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getImg() {
return img;
}
public void setImg(String img) {
this.img = img;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public Integer getSales() {
return sales;
}
public void setSales(Integer sales) {
this.sales = sales;
}
public Boolean getRecommendation() {
return recommendation;
}
public void setRecommendation(Boolean recommendation) {
this.recommendation = recommendation;
}
public Integer getRecoSort() {
return recoSort;
}
public void setRecoSort(Integer recoSort) {
this.recoSort = recoSort;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
接口实现方法:
/**
* 查询热门商品
* @param key 热门商品key
* @param pid 热门商品id
* @return 热门商品列表
*/
private List<Item> findItemsFromRedis(String key,String pid){
List<Object> hotProducts = redisTemplate.opsForList().range("hotProduct", 0, -1);
String jsonStr = JSONUtil.toJsonStr(JSONUtil.parse(hotProducts));
List<Item> items = JSONUtil.toList(jsonStr, Item.class);
List<Item> result = new ArrayList<>();
if(StrUtil.isNotEmpty(pid)){
for (Item item : items) {
if(item.getId().equals(pid)){
result.add(item);
}
}
} else {
result = items;
}
return result;
}