欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Springboot中Instant時間傳參及序列化詳解

 更新時間:2023年11月06日 10:27:37   作者:楊某人信了你的邪  
這篇文章主要介紹了Springboot中Instant時間傳參及序列化詳解,Instant是Java8引入的一個精度極高的時間類型,可以精確到納秒,但實際使用的時候不需要這么高的精確度,通常到毫秒就可以了,需要的朋友可以參考下

Instant時間傳參及序列化

在部分場景中,后臺的時間屬性用的不是Date或Long,而是Instant,Java8引入的一個精度極高的時間類型,可以精確到納秒,但實際使用的時候不需要這么高的精確度,通常到毫秒就可以了。

而在前后端傳參的時候需要對Instant類型進行序列化及反序列化等處理,默認情況下,ObjectMapper是不支持序列化Instant類型的,需要注冊JavaTimeModule才行,而且序列化的結(jié)果也不是時間戳,測試如下

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;

import java.time.Instant;

/**
 * Instant Jackson測試
 *
 * @author yangguirong
 */
@Slf4j
public class InstantTest {

    ObjectMapper objectMapper = new ObjectMapper();

    @Test
    void serializeTest() throws JsonProcessingException {
        objectMapper.registerModule(new JavaTimeModule());
        String str = objectMapper.writeValueAsString(Instant.now());
        log.info("serializeTest: {}", str);
        // serializeTest: 1691208180.052185000
    }

    @Test
    void deserializeTest() throws JsonProcessingException {
        objectMapper.registerModule(new JavaTimeModule());
        Instant instant = objectMapper.readValue("1691208180.052185000", Instant.class);
        log.info("deserializeTest: {}", instant);
        // deserializeTest: 2023-08-05T04:03:00.052185Z
    }
}

想要將其序列化為毫秒時間戳,需要對序列化及反序列化進行自定義

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.time.Instant;

/**
 * 自定義Instant序列化及反序列
 *
 * @author yangguirong
 */
public class InstantMillsTimeModule extends SimpleModule {

    public InstantMillsTimeModule() {
        this.addSerializer(Instant.class, new InstantMillisecondsSerializer());
        this.addDeserializer(Instant.class, new InstantMillisecondsDeserializer());
    }

    public static class InstantMillisecondsSerializer extends JsonSerializer<Instant> {
        @Override
        public void serialize(Instant instant, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            if (instant == null) {
                jsonGenerator.writeNull();
            } else {
                jsonGenerator.writeNumber(instant.toEpochMilli());
            }
        }
    }
    
    @Slf4j
    public static class InstantMillisecondsDeserializer extends JsonDeserializer<Instant> {
        @Override
        public Instant deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
            try {
                long mills = p.getValueAsLong();
                return mills > 0 ? Instant.ofEpochMilli(mills) : null;
            } catch (Exception e) {
                log.error("Instant類型反序列化失敗!val: {}, message: {}", p.getText(), e.getMessage());
            }
            return null;
        }
    }
}

再來測試一下自定義的序列化及反序列化方式

import com.example.websocket.config.InstantMillsTimeModule;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;

import java.time.Instant;

/**
 * Instant Jackson測試
 *
 * @author yangguirong
 */
@Slf4j
public class InstantTest {

    ObjectMapper objectMapper = new ObjectMapper();

    @Test
    void serializeTest() throws JsonProcessingException {
        objectMapper.registerModule(new JavaTimeModule());
        String str = objectMapper.writeValueAsString(Instant.now());
        log.info("serialize: {}", str);
        // serialize: 1691208180.052185000
    }

    @Test
    void deserializeTest() throws JsonProcessingException {
        objectMapper.registerModule(new JavaTimeModule());
        Instant instant = objectMapper.readValue("1691208180.052185000", Instant.class);
        log.info("deserialize: {}", instant);
        // deserialize: 2023-08-05T04:03:00.052185Z
    }

    @Test
    void millsSerializeTest() throws JsonProcessingException {
        objectMapper.registerModule(new InstantMillsTimeModule());
        String str = objectMapper.writeValueAsString(Instant.now());
        log.info("millsSerializeTest: {}", str);
        // millsSerializeTest: 1691208541018
    }

    @Test
    void millsDeserializeTest() throws JsonProcessingException {
        objectMapper.registerModule(new InstantMillsTimeModule());
        Instant instant = objectMapper.readValue("1691208541018", Instant.class);
        log.info("millsDeserializeTest: {}", instant);
        // deserialize: 2023-08-05T04:09:01.018Z
    }
}

可以看到,結(jié)果是符合預(yù)期的,可以在毫秒時間戳和Instant之間相互轉(zhuǎn)換。

在后臺配置SpringBoot的時候,需要考慮兩種情況,一種就是Instant作為RequestParam/PathVariable的情況,另一種是RequestBody/ResponseBody的情況。前者借助轉(zhuǎn)換器實現(xiàn),配置如下

import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.format.FormatterRegistry;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.time.Instant;

/**
 * web mvc設(shè)置
 *
 * @author yangguirong
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(instantConvert());
    }

    public Converter<String, Instant> instantConvert() {
        // 不能替換為lambda表達式
        return new Converter<String, Instant>() {
            @Override
            public Instant convert(String source) {
                if (StringUtils.hasText(source)) {
                    return Instant.ofEpochMilli(Long.parseLong(source));
                }
                return null;
            }
        };
    }
}

后者如果是局部配置,則在具體的實體類屬性上添加@JsonSerialize和@JsonDeserialize注解,在注解中指定序列化器和反序列化器即可。如果是全局配置,則可以按照如下方式進行配置,將InstantMillsTimeModule注冊為Bean,這個Bean會在JacksonAutoConfiguration中的StandardJackson2ObjectMapperBuilderCustomizer被自動注入,然后進行注冊。

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Jackson配置
 *
 * @author yangguirong
 */
@Configuration
@AutoConfigureBefore(JacksonAutoConfiguration.class)
public class JacksonCustomizerConfig {

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jacksonModuleRegistryCustomizer() {
        return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.featuresToDisable(
                DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, SerializationFeature.FAIL_ON_EMPTY_BEANS
        );
    }

    @Bean
    public InstantMillsTimeModule instantMillsTimeModule() {
        return new InstantMillsTimeModule();
    }
}

簡單的接口測試

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.time.Instant;

/**
 * instant測試
 *
 * @author yangguirong
 */
@Slf4j
@RequestMapping("instant")
@RestController
public class InstantTestController {

    @GetMapping("getInstant")
    public Instant getInstant() {
        return Instant.now();
    }

    @PutMapping("setInstant")
    public void setInstant(@RequestParam Instant instant) {
        log.info("setInstant: {}", instant);
    }

    @GetMapping("getInstantDemoVO")
    public DemoVO getInstantDemoVO() {
        return new DemoVO(Instant.now());
    }

    @PutMapping("setInstantDemoVO")
    public void setInstantDemoVO(@RequestBody DemoVO vo) {
        log.info("setInstantDemoVO:{}", vo);
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    static class DemoVO {
        private Instant instant;
    }
}

到此這篇關(guān)于Springboot中Instant時間傳參及序列化詳解的文章就介紹到這了,更多相關(guān)Instant時間傳參及序列化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • mybatis plus CU自動填充 和 軟刪除自動填充的實現(xiàn)方法

    mybatis plus CU自動填充 和 軟刪除自動填充的實現(xiàn)方法

    這篇文章主要介紹了mybatis plus CU自動填充 和 軟刪除自動填充的實現(xiàn)方法,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-07-07
  • Spring Boot 與 Kotlin 使用JdbcTemplate連接MySQL數(shù)據(jù)庫的方法

    Spring Boot 與 Kotlin 使用JdbcTemplate連接MySQL數(shù)據(jù)庫的方法

    本文介紹在Spring Boot基礎(chǔ)下配置數(shù)據(jù)源和通過 JdbcTemplate 編寫數(shù)據(jù)訪問的示例。感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧
    2018-01-01
  • 6個必備的Java并發(fā)面試種子題目合集

    6個必備的Java并發(fā)面試種子題目合集

    并發(fā)是Java面試的經(jīng)常會考到的知識點,這篇文章主要為大家整理了6個必備的Java并發(fā)面試種子題目,文中的示例代碼簡潔易懂,需要的可以學(xué)習(xí)一下
    2023-07-07
  • idea切換git地址并刷新右下角git分支

    idea切換git地址并刷新右下角git分支

    這篇文章主要介紹了idea切換git地址并刷新右下角git分支,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Mybatis中的mapper是如何和XMl關(guān)聯(lián)起來的

    Mybatis中的mapper是如何和XMl關(guān)聯(lián)起來的

    這篇文章主要介紹了Mybatis中的mapper是如何和XMl關(guān)聯(lián)起來的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • IntelliJ IDEA全局內(nèi)容搜索和替換教程圖解

    IntelliJ IDEA全局內(nèi)容搜索和替換教程圖解

    很多朋友在做項目時,會在整個項目里活指定文件夾下進行全局搜索和替換,下面小編給大家?guī)砹薎ntelliJ IDEA全局內(nèi)容搜索和替換教程圖解,需要的朋友參考下吧
    2018-04-04
  • java集合與數(shù)組的相同點和不同點

    java集合與數(shù)組的相同點和不同點

    今天小編就為大家分享一篇關(guān)于java集合與數(shù)組的相同點和不同點,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • Myeclipse 2016下Aptana安裝教程

    Myeclipse 2016下Aptana安裝教程

    這篇文章主要為大家詳細介紹了Myeclipse 2016下Aptana安裝教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • 一文帶你掌握Java ImageIO類

    一文帶你掌握Java ImageIO類

    Java中的ImageIO類是Java標準庫中用于處理圖像的一個非常常用的 API,它提供了讀取和寫入多種常見圖像格式的功能,如JPEG、PNG、BMP、GIF等,本文將全面詳細地介紹Java中的ImageIO類的使用方法,需要的朋友可以參考下
    2023-05-05
  • Java實現(xiàn)多路復(fù)用select模型實例詳解

    Java實現(xiàn)多路復(fù)用select模型實例詳解

    在計算機網(wǎng)絡(luò)中,多路復(fù)用(Multiplexing)指的是通過一種機制將多個 I/O 操作合并到同一個線程或進程中,從而提高系統(tǒng)的效率,在 Java 中,可以使用 Selector 類來實現(xiàn)基于 I/O 多路復(fù)用的模式,故本文給大家介紹了Java實現(xiàn)多路復(fù)用select模型實例,需要的朋友可以參考下
    2025-03-03

最新評論