GenericJackson2JsonRedisSerializer
-
对于这个不存在的属性, 需要标注为忽略, 否则, 反序列化时, 会报错。
-
主要也是因为,我们拿不到GenericJackson2JsonRedisSerializer中的mapper,不然,是可以修改mapper的反序列化特性的,把mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);关闭也可。
-
发现,在反序列化的时候,我们
并未提供具体反序列化的类!!!
,但是GenericJackson2JsonRedisSerializer却可以帮助我们反序列化为当时指定的类
,并且注意到,在序列化的时候,是存在@class这个字段的package com.zzhua.blog.config.redis;import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import lombok.Data; import org.junit.Test;import java.util.Date;@Data public class Person {private String name;private Integer age;private Date date;@JsonIgnore /* 对于这个不存在的属性, 需要标注为忽略, 否则, 反序列化时, 会报错。 */public Integer getEven() {return this.age % 2 == 0?1:0;}public Person() {}public Person(String name, Integer age,Date date) {this.name = name;this.age = age;this.date = date;}}
@Test public void test001() {GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();byte[] bytes = jackson2JsonRedisSerializer.serialize(new Person("zzhua", 19, new Date()));String s = new String(bytes, StandardCharsets.UTF_8);System.out.println(s);/* {"@class":"com.zzhua.blog.config.redis.Person","name":"zzhua","age":19,"date":["java.util.Date",1682245115549]} */Object o = jackson2JsonRedisSerializer.deserialize(s.getBytes(StandardCharsets.UTF_8));System.out.println(o);Person(name=zzhua, age=19, date=Sun Apr 23 18:18:35 CST 2023) }/* 和下面对比一下,原始的ObjectMapper的用法 */ @Test public void test002() throws Exception {ObjectMapper mapper = new ObjectMapper();System.out.println(mapper.writeValueAsString(new Person("zzhua",19, new Date())));/* {"name":"zzhua","age":19,"date":1682243545590} */mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);Person person = mapper.readValue("{\"name\":\"zzhua\",\"age\":19,\"date\":1682243545590,\"even\":0}", Person.class);System.out.println(person);}
-
Result是常用的返回类,带泛型,下面仍然能够保留原类信息
@Test public void test003() {GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();Result<Person> result = new Result<>();result.setData(new Person("zzhua", 19, new Date()));byte[] bytes = jackson2JsonRedisSerializer.serialize(result);String s = new String(bytes, StandardCharsets.UTF_8);System.out.println(s);/* {"@class":"com.zzhua.blog.util.Result","code":0,"msg":null,"data":{"@class":"com.zzhua.blog.config.redis.Person","name":"zzhua","age":19,"date":["java.util.Date",1682245790213]}}*/Object o = jackson2JsonRedisSerializer.deserialize(s.getBytes(StandardCharsets.UTF_8));System.out.println(o);/* Result(code=0, msg=null, data=Person(name=zzhua, age=19, date=Sun Apr 23 18:29:50 CST 2023)) */}
配置RedisTemplate
引入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.6.2</version></dependency><!--Lettuce是 一 个 基 于 Netty的 NIO方 式 处 理 Redis的 技 术 --><dependency><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId></dependency>
RedisConfig
@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(redisConnectionFactory);RedisSerializer<String> stringRedisSerializer = RedisSerializer.string();GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();redisTemplate.setKeySerializer(stringRedisSerializer);redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);redisTemplate.setHashKeySerializer(stringRedisSerializer);redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);return redisTemplate;}}
RedisService
package com.zzhua.blog.config.redis;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;import java.util.Collection;
import java.util.concurrent.TimeUnit;@Component
public class RedisService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;/* key 是否存在 */public Boolean existKey(String key) {return redisTemplate.hasKey(key);}/* 设置 key 失效时间 */public Boolean expireKey(String key, long timeInSeconds) {return redisTemplate.expire(key, timeInSeconds, TimeUnit.SECONDS);}/* 移除 key */public Boolean removeKey(String key) {return redisTemplate.delete(key);}/* 移除多个 key */public Boolean removeKeys(Collection<String> keys) {return redisTemplate.delete(keys) > 0;}public Long incr(String key) {return redisTemplate.opsForValue().increment(key);}public Long incr(String key, long delta) {return redisTemplate.opsForValue().increment(key, delta);}public void set(String key, Object obj, long timeInSeconds) {redisTemplate.opsForValue().set(key, obj, timeInSeconds, TimeUnit.SECONDS);}public void set(String key, Object obj) {redisTemplate.opsForValue().set(key, obj);}public <T> T get(String key) {return (T)redisTemplate.opsForValue().get(key);}}