最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot 如何實(shí)現(xiàn)自定義Redis序列化

 更新時(shí)間:2021年10月12日 14:11:36   作者:虎口脫險(xiǎn)OvO  
這篇文章主要介紹了SpringBoot 如何實(shí)現(xiàn)自定義Redis序列化方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

問題

在使用RedisTemplate存儲對象時(shí),如果采用JDK默認(rèn)的序列化方式,數(shù)據(jù)會出現(xiàn)許多編碼字符,辨析度不高。比如一個(gè)空的User對象,存儲到redis后如下:

這些使用JDK默認(rèn)序列化方式序列化后的數(shù)據(jù)簡直慘不忍睹,在使用命令行查詢數(shù)據(jù)時(shí)會很頭疼。

如何使數(shù)據(jù)更容易辨別呢?

一種辦法是使用StringRedisTemplate,在存入redis前先將數(shù)據(jù)處理成字符串格式再存入redis,但這種方式的缺點(diǎn)就是每次存入數(shù)據(jù)前都要手動(dòng)對非字符串?dāng)?shù)據(jù)進(jìn)行處理。

另一種方法就是自定義序列化方式,只需要使用RedisTemplate就能按照自定義的序列化方式存儲對象。

這里使用的是第二種方法。

環(huán)境

這里使用的SpringBoot2.0.5版本。

依賴信息:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.5.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <dependency>
        <groupId>joda-time</groupId>
        <artifactId>joda-time</artifactId>
        <version>2.9.9</version>
    </dependency>
</dependencies>

SpringBoot啟動(dòng)類:

@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class);
    }
}

User實(shí)體類:

public class User implements Serializable {
    private String username;
    private String password;
    private DateTime birthday;
    public DateTime getBirthday() {
        return birthday;
    }
    public void setBirthday(DateTime birthday) {
        this.birthday = birthday;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", birthday=" + birthday +
                '}';
    }
}

測試類:

@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisTest {
    @Autowired
    private RedisTemplate redisTemplate;
    @Test
    public void testRedis(){
        User user = new User();
        user.setUsername("charviki");
        user.setPassword("123456");
        redisTemplate.opsForValue().set("user", user);
        User user1 = (User) redisTemplate.opsForValue().get("user");
        System.out.println(user1);
    }
}

入口點(diǎn)

當(dāng)引入redis啟動(dòng)器時(shí),SpringBoot通過RedisTemplate這個(gè)類自動(dòng)幫我們配置了許多默認(rèn)參數(shù),包括redis主機(jī),默認(rèn)序列化方式等。找到RedisAutoConfiguration這個(gè)類,這個(gè)類中有如下代碼:

這里使用了注解@ConditionalOnMissingBean(name = "redisTemplate"),大致意思就是如果Spring容器中沒有RedisTemplate這個(gè)bean,就會返回一個(gè)默認(rèn)的RedisTemplate(配置信息都在這個(gè)類里面)。

到這里就有大致的思路了,要想實(shí)現(xiàn)自定義redis序列化,首先定義一個(gè)返回類型為RedisTemplate的bean,并將該bean交由Spring容器管理。

實(shí)現(xiàn)自定義序列化

定義RedisConfig類,自定義序列化:

@Component
public class RedisConfig {
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
        RedisTemplate redisTemplate = new RedisTemplate();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // 自定義key序列化方式,直接將String字符串直接作為redis中的key
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringRedisSerializer);
        // 自定義value序列化方式,序列化成json格式
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        return redisTemplate;
    }
}

運(yùn)行測試類,程序報(bào)錯(cuò),錯(cuò)誤信息如下:

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to cn.charviki.pojo.User

 at cn.charviki.test.RedisTest.testRedis(RedisTest.java:33)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:498)
 at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
 at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
 at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
 at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
 at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)
 at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
 at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
 at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
 at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
 at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
 at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
 at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
 at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
 at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
 at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
 at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
 at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
 at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
 at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
 at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
 at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
 at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
 at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
 at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
 at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
 at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

先不管錯(cuò)誤信息,先去在redis中查看數(shù)據(jù),如下:

也就是說數(shù)據(jù)存進(jìn)去了,但是取不出來。

這個(gè)時(shí)候回去看錯(cuò)誤信息:

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to cn.charviki.pojo.User

看異常名也可以知道,類轉(zhuǎn)換異常,即從redis中取數(shù)據(jù)后反序列化異常。

這個(gè)異常出現(xiàn)的原因是在序列化的時(shí)候我們沒有加入類信息,取出來的時(shí)候jvm找不到類信息,無法將該json數(shù)據(jù)轉(zhuǎn)換對應(yīng)的類。

解決這個(gè)問題只需要在對值序列化的時(shí)候加入類信息,修改redisTemplate方法如下:

@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
    RedisTemplate redisTemplate = new RedisTemplate();
    redisTemplate.setConnectionFactory(redisConnectionFactory);
    // 自定義key序列化方式,直接將String字符串直接作為redis中的key
    StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
    redisTemplate.setKeySerializer(stringRedisSerializer);
    // 自定義value序列化方式,序列化成json格式
    Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new 					Jackson2JsonRedisSerializer(Object.class);
    //jackson底層的序列化和反序列化使用的是ObjectMapper,我們可以通過ObjectMapper設(shè)置序列化信息
    // 設(shè)置值的默認(rèn)類型,即類信息
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    // 添加進(jìn)序列化中
    jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
    redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
    return redisTemplate;
}

再次運(yùn)行測試類,控制臺打印信息如下:

這里我們就實(shí)現(xiàn)了將對象使用json的序列化方式,但是這里會出現(xiàn)一個(gè)問題,就是當(dāng)對象中成員變量的數(shù)據(jù)類型不是JDK中的數(shù)據(jù)類型時(shí)就會出現(xiàn)問題。比如說User類中有一個(gè)DateTime類型的birthday變量,這個(gè)DateTime是joda-time包下的一個(gè)日期類,在上面pom文件中已經(jīng)引入了依賴。在上面測試類中我們沒有為這個(gè)變量值賦值,現(xiàn)在讓我們修改測試類:

@Test
public void testRedis(){
    User user = new User();
    user.setUsername("charviki");
    user.setPassword("123456");
    // 這里打印出dateTime,方便和redis中對比
    DateTime dateTime = new DateTime();
    System.out.println("dateTime = " + dateTime);
    user.setBirthday(dateTime);
    redisTemplate.opsForValue().set("user",user);
    User user1 = (User) redisTemplate.opsForValue().get("user");
    System.out.println(user1);
}

運(yùn)行測試類,這個(gè)時(shí)候程序報(bào)錯(cuò),錯(cuò)誤信息如下:

org.springframework.data.redis.serializer.SerializationException: Could not read JSON: Unrecognized field "era" (class org.joda.time.DateTime), not marked as ignorable (2 known properties: "chronology", "millis"])
 at [Source: (byte[])"["cn.charviki.pojo.User",{"username":"charviki","password":"123456","birthday":{"era":1,"dayOfMonth":16,"dayOfWeek":3,"dayOfYear":289,"year":2019,"hourOfDay":15,"minuteOfHour":30,"yearOfEra":2019,"yearOfCentury":19,"monthOfYear":10,"weekyear":2019,"centuryOfEra":20,"millisOfDay":55811047,"secondOfDay":55811,"minuteOfDay":930,"weekOfWeekyear":42,"millisOfSecond":47,"secondOfMinute":11,"zone":["org.joda.time.tz.CachedDateTimeZone",{"fixed":false,"uncachedZone":["org.joda.time.tz.DateTimeZoneBuilde"[truncated 439 bytes]; line: 1, column: 88] (through reference chain: cn.charviki.pojo.User["birthday"]->org.joda.time.DateTime["era"]); nested exception is com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "era" (class org.joda.time.DateTime), not marked as ignorable (2 known properties: "chronology", "millis"])
 at [Source: (byte[])"["cn.charviki.pojo.User",{"username":"charviki","password":"123456","birthday":{"era":1,"dayOfMonth":16,"dayOfWeek":3,"dayOfYear":289,"year":2019,"hourOfDay":15,"minuteOfHour":30,"yearOfEra":2019,"yearOfCentury":19,"monthOfYear":10,"weekyear":2019,"centuryOfEra":20,"millisOfDay":55811047,"secondOfDay":55811,"minuteOfDay":930,"weekOfWeekyear":42,"millisOfSecond":47,"secondOfMinute":11,"zone":["org.joda.time.tz.CachedDateTimeZone",{"fixed":false,"uncachedZone":["org.joda.time.tz.DateTimeZoneBuilde"[truncated 439 bytes]; line: 1, column: 88] (through reference chain: cn.charviki.pojo.User["birthday"]->org.joda.time.DateTime["era"])

 at org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer.deserialize(Jackson2JsonRedisSerializer.java:75)
 at org.springframework.data.redis.core.AbstractOperations.deserializeValue(AbstractOperations.java:334)
 at org.springframework.data.redis.core.AbstractOperations$ValueDeserializingRedisCallback.doInRedis(AbstractOperations.java:60)
 at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:224)
 at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:184)
 at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:95)
 at org.springframework.data.redis.core.DefaultValueOperations.get(DefaultValueOperations.java:48)
 at cn.charviki.test.RedisTest.testRedis(RedisTest.java:34)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:498)
 at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
 at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
 at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
 at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
 at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)
 at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
 at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
 at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
 at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
 at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
 at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
 at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
 at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
 at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
 at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
 at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
 at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
 at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
 at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
 at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
 at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
 at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
 at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
 at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
 at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
 at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "era" (class org.joda.time.DateTime), not marked as ignorable (2 known properties: "chronology", "millis"])
 at [Source: (byte[])"["cn.charviki.pojo.User",{"username":"charviki","password":"123456","birthday":{"era":1,"dayOfMonth":16,"dayOfWeek":3,"dayOfYear":289,"year":2019,"hourOfDay":15,"minuteOfHour":30,"yearOfEra":2019,"yearOfCentury":19,"monthOfYear":10,"weekyear":2019,"centuryOfEra":20,"millisOfDay":55811047,"secondOfDay":55811,"minuteOfDay":930,"weekOfWeekyear":42,"millisOfSecond":47,"secondOfMinute":11,"zone":["org.joda.time.tz.CachedDateTimeZone",{"fixed":false,"uncachedZone":["org.joda.time.tz.DateTimeZoneBuilde"[truncated 439 bytes]; line: 1, column: 88] (through reference chain: cn.charviki.pojo.User["birthday"]->org.joda.time.DateTime["era"])
 at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:60)
 at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:822)
 at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1152)
 at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1589)
 at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1567)
 at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:294)
 at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
 at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:127)
 at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
 at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
 at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer._deserialize(AsArrayTypeDeserializer.java:116)
 at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer.deserializeTypedFromAny(AsArrayTypeDeserializer.java:71)
 at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.deserializeWithType(UntypedObjectDeserializer.java:712)
 at com.fasterxml.jackson.databind.deser.impl.TypeWrappedDeserializer.deserialize(TypeWrappedDeserializer.java:68)
 at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
 at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3129)
 at org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer.deserialize(Jackson2JsonRedisSerializer.java:73)
 ... 37 more

跟前面一樣先查看redis中的數(shù)據(jù):

查看控制臺打印的DataTime數(shù)據(jù):

對比控制臺數(shù)據(jù)和redis中的數(shù)據(jù),redisTemplate將DataTime使用默認(rèn)的json序列化后,多了許多字段。

再看報(bào)錯(cuò)信息,問題同樣出在反序列化上。從報(bào)錯(cuò)信息中我們可以看出,在反序列化的時(shí)候找不到相應(yīng)的字段。這里的解決版本是實(shí)現(xiàn)針對DataTime類型的序列化和反序列化器,注冊到ObjectMapper中,實(shí)現(xiàn)對json序列化器的擴(kuò)展。

先自定義序列化器,這里定義序列化器JodaDateTimeJsonSerializer和反序列化器JodaDateTimeJsonDeserializer,兩者都要繼承JsonDeserializer并重寫父類serialize()或deserialize方法。實(shí)現(xiàn)代碼如下:

// JodaDateTimeJsonSerializer.java
public class JodaDateTimeJsonSerializer extends JsonSerializer<DateTime> {
    @Override
    public void serialize(DateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        // 序列化
        gen.writeString(value.toString("yyyy-MM-dd HH:mm:ss"));
    }
}
// JodaDateTimeJsonDeserializer.java
public class JodaDateTimeJsonDeserializer extends JsonDeserializer<DateTime> {
    @Override
    public DateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        String dateString = p.readValueAs(String.class);
        DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
        // 反序列化
        return DateTime.parse(dateString,dateTimeFormatter);
    }
}

將自定義序列化器通過ObjectMapper注冊到j(luò)son序列化器中,修改redisTemplate方法如下:

@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
    RedisTemplate redisTemplate = new RedisTemplate();
    redisTemplate.setConnectionFactory(redisConnectionFactory);
    // 自定義key序列化方式,直接將String字符串直接作為redis中的key
    StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
    redisTemplate.setKeySerializer(stringRedisSerializer);
    // 自定義value序列化方式,序列化成json格式
    Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
    //jackson底層的序列化和反序列化使用的是ObjectMapper,我們可以通過ObjectMapper設(shè)置序列化信息
    // 設(shè)置值的默認(rèn)類型,即類信息
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    // SimpleModule用于設(shè)置自定義序列化器
    SimpleModule simpleModule = new SimpleModule();
    simpleModule.addSerializer(DateTime.class,new JodaDateTimeJsonSerializer());
    simpleModule.addDeserializer(DateTime.class,new JodaDateTimeJsonDeserializer());
    objectMapper.registerModule(simpleModule);
    // 添加進(jìn)json序列化器中
    jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
    redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
    return redisTemplate;
}

這個(gè)時(shí)候再運(yùn)行測試類就沒什么問題了。

控制臺打印信息如下:

redis中的數(shù)據(jù)信息如下:

網(wǎng)上還有一種更加簡便的方法就是使用jackson提供的包,引入依賴:

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-joda</artifactId>
    <version>2.9.9</version>
</dependency>

這個(gè)包已經(jīng)幫我們實(shí)現(xiàn)了關(guān)于joda-time的序列化與反序列化器,我們只需要在redisTemplate方法中將對應(yīng)的SimpleModel注冊到ObjectMapper中就行:

objectMapper.registerModule(new JodaModule());

這樣也可以達(dá)到同樣的效果。

小結(jié)

總之,想要在SpringBoot中實(shí)現(xiàn)redis的自定義序列化,需要自定義創(chuàng)建一個(gè)redisTemplate的bean,設(shè)置要使用的序列化方式。通過ObjectMapper設(shè)置一些自定義序列化信息,如反序列化所要用到的類信息等。還可以對特定的數(shù)據(jù)類型進(jìn)行自定義序列化,只需要通過SimpleModel注冊到相應(yīng)的序列化器即可。最后再將該bean交由Spring容器管理。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解SpringBoot 添加對JSP的支持(附常見坑點(diǎn))

    詳解SpringBoot 添加對JSP的支持(附常見坑點(diǎn))

    這篇文章主要介紹了詳解SpringBoot 添加對JSP的支持(附常見坑點(diǎn)),非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2017-10-10
  • java實(shí)現(xiàn)隨機(jī)生成驗(yàn)證碼圖片

    java實(shí)現(xiàn)隨機(jī)生成驗(yàn)證碼圖片

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)隨機(jī)生成驗(yàn)證碼圖片,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • 解決Springboot get請求是參數(shù)過長的情況

    解決Springboot get請求是參數(shù)過長的情況

    這篇文章主要介紹了解決Springboot get請求是參數(shù)過長的情況,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • springboot vue組件開發(fā)實(shí)現(xiàn)接口斷言功能

    springboot vue組件開發(fā)實(shí)現(xiàn)接口斷言功能

    這篇文章主要為大家介紹了springboot+vue組件開發(fā)實(shí)現(xiàn)接口斷言功能,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • SpringBoot3實(shí)現(xiàn)統(tǒng)一結(jié)果封裝的示例代碼

    SpringBoot3實(shí)現(xiàn)統(tǒng)一結(jié)果封裝的示例代碼

    Spring Boot進(jìn)行統(tǒng)一結(jié)果封裝的主要目的是提高開發(fā)效率、降低代碼重復(fù)率,并且提供一致的API響應(yīng)格式,從而簡化前后端交互和錯(cuò)誤處理,所以本文給大家介紹了SpringBoot3實(shí)現(xiàn)統(tǒng)一結(jié)果封裝的方法,需要的朋友可以參考下
    2024-03-03
  • 詳解如何獲取PreparedStatement參數(shù)示例詳解

    詳解如何獲取PreparedStatement參數(shù)示例詳解

    這篇文章主要為大家介紹了詳解如何獲取PreparedStatement參數(shù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • SpringBoot整合BCrypt實(shí)現(xiàn)密碼加密

    SpringBoot整合BCrypt實(shí)現(xiàn)密碼加密

    這篇文章主要為大家詳細(xì)介紹了SpringBoot整合BCrypt進(jìn)行密碼加密,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • Java實(shí)現(xiàn)并查集

    Java實(shí)現(xiàn)并查集

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)并查集,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • java常見面試題及答案匯總

    java常見面試題及答案匯總

    本文提供Java面試題集錦,涵蓋封裝、繼承、多態(tài)等核心概念,旨在幫助求職者全面復(fù)習(xí),提升面試表現(xiàn),從基礎(chǔ)知識到實(shí)際應(yīng)用,內(nèi)容豐富,適合各類求職者,需要的朋友可以參考下
    2024-09-09
  • SpringBoot?Http遠(yuǎn)程調(diào)用的方法

    SpringBoot?Http遠(yuǎn)程調(diào)用的方法

    這篇文章主要為大家詳細(xì)介紹了SpringBoot?Http遠(yuǎn)程調(diào)用的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08

最新評論

高要市| 安乡县| 乐清市| 沅陵县| 马山县| 九江市| 双辽市| 尼木县| 东莞市| 股票| 富顺县| 大姚县| 夏邑县| 米脂县| 贺州市| 遂平县| 从化市| 岫岩| 灵石县| 永福县| 永兴县| 广南县| 文化| 玛多县| 华蓥市| 麻江县| 治多县| 乐陵市| 沙雅县| 社旗县| 彰化县| 英德市| 东乡| 岑溪市| 平安县| 河源市| 兴隆县| 横峰县| 轮台县| 海宁市| 鄄城县|