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

詳解springboot接口如何優(yōu)雅的接收時(shí)間類型參數(shù)

 更新時(shí)間:2023年09月19日 08:40:38   作者:趙俠客  
這篇文章主要為大家詳細(xì)介紹了springboot的接口如何優(yōu)雅的接收時(shí)間類型參數(shù),文中為大家整理了三種常見(jiàn)的方法,希望對(duì)大家有一定的幫助

前言

在上文中我們總結(jié)了前后端Http接口傳參的常用方法,本文主要針對(duì)參數(shù)中的時(shí)間字段如何處理做個(gè)總結(jié),由于時(shí)間的格式有很多種,比較常用的有時(shí)間戳格式、UTC時(shí)間格式、標(biāo)準(zhǔn)時(shí)間格式等,而且時(shí)間參數(shù)出現(xiàn)的位置可能在URL上,可能在Body中,也可能在Header中,所以本文提供一套優(yōu)雅的處理時(shí)間格式字段的解決方案。

時(shí)間格式不做任務(wù)處理會(huì)怎樣?

我們創(chuàng)建一個(gè)簡(jiǎn)單的接口,想通過(guò)@PathVariable接收Date類型的時(shí)間參數(shù),和通過(guò)@RequestParam接收LocalDateTime類型的時(shí)間參數(shù),并且想通過(guò)@RequestBody來(lái)接收J(rèn)SON中的時(shí)間參數(shù):

    @GetMapping("/time/{today}")
    public UserDTO time(@PathVariable Date today, @RequestParam LocalDateTime time,@RequestBody UserDTO userDTO) {
        return userDTO;
    }
    @Data
    public class UserDTO {
        private Long id;
        private String userName;
        private Date  now;
        private Date  day;
        private LocalDateTime time;
        private LocalDateTime timeStack;
    }

HTTP測(cè)試請(qǐng)求報(bào)文:

GET http://localhost:80/time/2023-09-10?time=2023-09-15 11:11:11
Accept: application/json
Content-Type: application/json
{
    "id":1,
    "now":"2023-09-15 13:50:10",
    "day":"2023-09-15",
    "time": "2023-09-15 13:50:10",
    "timeStack": 1694757010407
}

結(jié)果:

如果不做任務(wù)處理,SpringBoot是不能自動(dòng)幫我們把接口中的時(shí)間參數(shù)轉(zhuǎn)成我們想要的時(shí)間格式的,默認(rèn)是用String接收的,如果直接用LocalDateTime或者Date來(lái)接收會(huì)報(bào)一個(gè)類型轉(zhuǎn)換錯(cuò)誤。這個(gè)也是比較好理解的,因?yàn)闀r(shí)間格式太多了,在不知道具體時(shí)間格式的情況下,框架也無(wú)法解析時(shí)間,只能用String接收了,最后將String轉(zhuǎn)成時(shí)間類型肯定就報(bào)錯(cuò)了。當(dāng)然我們可以使用String接收,再手動(dòng)轉(zhuǎn)成對(duì)應(yīng)的時(shí)間格式,這個(gè)方法太原始了,接下來(lái)我們看看不同級(jí)別是如何處理時(shí)間字段的。

Resolved [org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.time.LocalDateTime'; 
Resolved [org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.util.Date';

青銅解決方案

我們知道SpringMVC接收參數(shù)時(shí)自動(dòng)將參數(shù)注入到我們的JAVA對(duì)象中是在WebDataBinder中實(shí)現(xiàn)的,SpringMVC給我們提供了@InitBinder,可以在接收參數(shù)之前對(duì)參數(shù)解析進(jìn)行初始化設(shè)置,那我們可以在Controller中增加@InitBinder,然后拿到WebDataBinder對(duì)象,自定義LocalDateTime和Date兩種CustomEditor這樣我們使用@PathVariable@RequestParam時(shí)就可以自動(dòng)將String轉(zhuǎn)成時(shí)間格式了。但是@RequestBody默認(rèn)是使用Jackson做JSON數(shù)據(jù)解析的,所以還是不能處理對(duì)象中的時(shí)間格式,我們可以在時(shí)間字段上增加@JsonFormat注解來(lái)指定時(shí)間格式,從而讓@RequestBody也可以自動(dòng)解析時(shí)間格式。

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(LocalDateTime.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) {
                setValue(DateUtil.parseLocalDateTime(text));
            }
        });
        binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) {
                setValue(DateUtil.parse(text,NORM_DATETIME_PATTERN,NORM_DATE_PATTERN));
            }
        });
    }
    @Data
    public class UserDTO {
        private Long id;
        private String userName;
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
        private Date  now;
        @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
        private Date  day;
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
        private LocalDateTime time;
        //private LocalDateTime timeStack;
    }

青銅解析方案存在的問(wèn)題:

  • @InitBinder作用域只是當(dāng)前的Controller,如果我用100個(gè)Controller難道我要寫100個(gè)@InitBinder
  • @JsonFormat 也是每個(gè)字段上都要增加個(gè)注解,而且只能支持一種時(shí)間格式,如果我們還要支持時(shí)間戳格式就沒(méi)法做到了。

白銀解決方案

針對(duì)青銅解析方案存在的問(wèn)題1,我們的解決方案是使用@ControllerAdvice,這樣就不用在每個(gè)Controller是都添加@InitBinder

@ControllerAdvice
public class GlobalControllerAdvice {
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(LocalDateTime.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) {
                setValue(DateUtil.parseLocalDateTime(text));
            }
        });
        binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) {
                setValue(DateUtil.parse(text,NORM_DATETIME_PATTERN,NORM_DATE_PATTERN));
            }
        });
    }
}

針對(duì)青銅方案存在的問(wèn)題2,我們的分析是,既然SpringMvc解析JSON使用的是Jackson ,那么我們就可以讓SpringMVC使用我們自定義的Mapper來(lái)解析JSON, 我們?cè)?code>@Configuration增加ObjectMapper, 然后自定義LocalDateTimeSerializerLocalDateTimeDeserializer的序列化的反序處理器,這樣我們就不需要每個(gè)字段都添加上@JsonFormat了,Jaskson在解析JSON數(shù)據(jù)時(shí)遇到參數(shù)接收類型是LocalDateTime類型時(shí)會(huì)直接使用我們的自定義處理器,這樣就不會(huì)報(bào)字段轉(zhuǎn)換錯(cuò)誤了,是不是一個(gè)一個(gè)寫@JsonFormat優(yōu)雅了許多?

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Bean
    @Primary
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
        module.addSerializer(Date.class, new DateTimeSerializer());
        module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());
        module.addDeserializer(Date.class, new DateTimeDeserializer());
        mapper.registerModule(module);
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        return JsonUtils.getMapper();
    }
}
public class DateTimeDeserializer extends StdDeserializer<Date> {
    public DateTimeDeserializer() {
        this(null);
    }
    public DateTimeDeserializer(Class<?> vc) {
        super(vc);
    }
    @Override
    public Date deserialize(JsonParser jp, DeserializationContext ctx)
            throws IOException {
        String value = jp.getValueAsString();
            return DateUtil.parse(value,NORM_DATETIME_PATTERN,NORM_DATE_PATTERN);
    }
}
public class DateTimeSerializer extends StdSerializer<Date> {
    public DateTimeSerializer() {
        this(null);
    }
    public DateTimeSerializer(Class<Date> t) {
        super(t);
    }
    @Override
    public void serialize(Date value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
        jgen.writeString(DateUtil.format(value, DatePattern.NORM_DATETIME_PATTERN));
    }
}
public class LocalDateTimeDeserializer extends StdDeserializer<LocalDateTime> {
    public LocalDateTimeDeserializer() {
        this(null);
    }
    public LocalDateTimeDeserializer(Class<?> vc) {
        super(vc);
    }
    @Override
    public LocalDateTime deserialize(JsonParser jp, DeserializationContext ctx)
            throws IOException {
        String value = jp.getValueAsString();
        if (StrUtil.isNumeric(value)) {
            Date date = new Date(jp.getLongValue());
            return LocalDateTime.ofInstant(date.toInstant(),  ZoneId.of("Asia/Shanghai"));
        } else {
            return DateUtil.parseLocalDateTime(value);
        }
    }
}
public class LocalDateTimeSerializer extends StdSerializer<LocalDateTime> {
    public LocalDateTimeSerializer() {
        this(null);
    }
    public LocalDateTimeSerializer(Class<LocalDateTime> t) {
        super(t);
    }
    @Override
    public void serialize(LocalDateTime value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
        jgen.writeString(LocalDateTimeUtil.formatNormal(value));
    }
}

存在問(wèn)題:

@ControllerAdvice基于切面去做攔截,每個(gè)接口都需要經(jīng)過(guò)攔截,性能和優(yōu)雅性不是很好,能不能像Jackson一樣優(yōu)雅的處理呢?

王者解決方案

我們?cè)?code>Configuration中添加Converter<String, LocalDateTime> stringLocalDateTimeConverter()Converter<String, Date> stringDateTimeConverter() ,自定義Converter轉(zhuǎn)換時(shí)間類型, 這樣不管你是JSON數(shù)據(jù)傳參還是URL傳參數(shù)或是Header傳參,也不管你接收的時(shí)間是類型使用Date還是LocalDateTime,更不管你的時(shí)間格式是標(biāo)準(zhǔn)時(shí)間格式還是時(shí)間戳,統(tǒng)統(tǒng)自動(dòng)解決了時(shí)間自動(dòng)接收問(wèn)題,這樣是不是優(yōu)雅多了?

  
@Configuration
public class WebConfig  {
    @Bean
    @Primary
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
        module.addSerializer(Date.class, new DateTimeSerializer());
        module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());
        module.addDeserializer(Date.class, new DateTimeDeserializer());
        mapper.registerModule(module);
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        return JsonUtils.getMapper();
    }
    @Bean
    public Converter<String, LocalDateTime> stringLocalDateTimeConverter() {
        return new Converter<String, LocalDateTime>() {
            @Override
            public LocalDateTime convert(String source) {
                if (StrUtil.isNumeric(source)) {
                    return LocalDateTimeUtil.of(Long.parseLong(source));
                } else {
                    return DateUtil.parseLocalDateTime(source);
                }
            }
        };
    }
    @Bean
    public Converter<String, Date> stringDateTimeConverter() {
        return new Converter<String, Date>() {
            @Override
            public Date convert(String source) {
                if (StrUtil.isNumeric(source)) {
                    return new Date(Long.parseLong(source));
                } else {
                    return DateUtil.parse(source);
                }
            }
        };
    }
}

總結(jié)

本文介紹了在SpringBoot項(xiàng)目開(kāi)發(fā)中如何優(yōu)雅的接收HTTP協(xié)議中的時(shí)間類型的參數(shù)。時(shí)間參數(shù)可以出現(xiàn)在URL Path、queryString、FormData、BodyJSON、HTTP header中,時(shí)間格式可以是標(biāo)題格式,時(shí)間戳,接收時(shí)間參數(shù)可以是Date,LocalDateTime,非常優(yōu)雅的全局處理了接口中接口時(shí)間類型字段問(wèn)題。

到此這篇關(guān)于詳解springboot接口如何優(yōu)雅的接收時(shí)間類型參數(shù)的文章就介紹到這了,更多相關(guān)springboot接收參數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring cloud gateway(Web MVC)的深入使用

    Spring cloud gateway(Web MVC)的深入使用

    本文詳細(xì)介紹了Spring Cloud Gateway的使用,包括工程搭建、路由配置、自定義過(guò)濾器和謂詞的實(shí)現(xiàn)與使用,以及效果驗(yàn)證,感興趣的朋友跟隨小編一起看看吧
    2026-02-02
  • Mybatis-Plus 自動(dòng)填充失效問(wèn)題解決

    Mybatis-Plus 自動(dòng)填充失效問(wèn)題解決

    在使用MyBatis-Plus時(shí),自動(dòng)填充功能可能會(huì)失效,這通常與版本和配置有關(guān),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-10-10
  • SpringBoot如何使用內(nèi)嵌Tomcat問(wèn)題

    SpringBoot如何使用內(nèi)嵌Tomcat問(wèn)題

    這篇文章主要介紹了SpringBoot如何使用內(nèi)嵌Tomcat問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • Java 線程池+分布式實(shí)現(xiàn)代碼

    Java 線程池+分布式實(shí)現(xiàn)代碼

    在 Java 開(kāi)發(fā)中,"池" 通過(guò)預(yù)先創(chuàng)建并管理一定數(shù)量的資源,避免頻繁創(chuàng)建和銷毀資源帶來(lái)的性能開(kāi)銷,從而提高系統(tǒng)效率,這篇文章主要介紹了Java 線程池+分布式實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2025-09-09
  • SpringCache 緩存使用方案總結(jié)

    SpringCache 緩存使用方案總結(jié)

    在基于SpringBoot3.x集成JetCache時(shí)遇到問(wèn)題,決定采用SpringCache作為替代方案,本文詳細(xì)介紹了SpringCache本地緩存(Caffeine)和本地+遠(yuǎn)程(Redis)混合緩存的配置和使用方法,并總結(jié)了常用的緩存注解參數(shù)及其含義,感興趣的朋友跟隨小編一起看看吧
    2026-02-02
  • 基于java查找最長(zhǎng)字符串代碼實(shí)例

    基于java查找最長(zhǎng)字符串代碼實(shí)例

    這篇文章主要介紹了基于java查找最長(zhǎng)字符串代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • 使用Java+FFmpeg實(shí)現(xiàn)視頻分片合并(生成list.txt自動(dòng)合并)

    使用Java+FFmpeg實(shí)現(xiàn)視頻分片合并(生成list.txt自動(dòng)合并)

    在很多視頻處理場(chǎng)景中,我們會(huì)將一個(gè)錄制任務(wù)拆成多個(gè)小片段,多個(gè)分片合并成一個(gè)完整視頻是一個(gè)常見(jiàn)需求,所以本文給大家介紹了Java 調(diào)用 FFmpeg 生成用于合并的視頻列表文件 list.txt,并執(zhí)行合并命令生成最終視頻,需要的朋友可以參考下
    2026-02-02
  • java單例模式使用及注意事項(xiàng)

    java單例模式使用及注意事項(xiàng)

    這篇文章主要介紹了java單例模式使用及注意事項(xiàng),需要的朋友可以參考下
    2014-04-04
  • MyBatis中高級(jí)多表查詢(ResultMap、association、collection)詳解

    MyBatis中高級(jí)多表查詢(ResultMap、association、collection)詳解

    文章主要介紹了MyBatis中高級(jí)多表查詢的四種方式:ResultMap、association、collection以及自連接查詢,通過(guò)定義接口的抽象方法、編寫mapper.xml和測(cè)試類,詳細(xì)展示了如何根據(jù)復(fù)雜數(shù)據(jù)結(jié)構(gòu)進(jìn)行數(shù)據(jù)的裝配和查詢,感興趣的朋友一起看看吧
    2024-11-11
  • Springboot 整合 Java DL4J 打造文本摘要生成系統(tǒng)

    Springboot 整合 Java DL4J 打造文本摘要生成系統(tǒng)

    本文介紹了如何使用SpringBoot整合JavaDeeplearning4j構(gòu)建文本摘要生成系統(tǒng),該系統(tǒng)能夠自動(dòng)從長(zhǎng)篇文本中提取關(guān)鍵信息,生成簡(jiǎn)潔的摘要,幫助用戶快速了解文本的主要內(nèi)容,技術(shù)實(shí)現(xiàn)包括使用LSTM神經(jīng)網(wǎng)絡(luò)進(jìn)行模型構(gòu)建和訓(xùn)練,并通過(guò)SpringBoot集成RESTfulAPI接口
    2024-11-11

最新評(píng)論

安庆市| 陆丰市| 汉阴县| 宁都县| 晋宁县| 广丰县| 克什克腾旗| 绍兴县| 噶尔县| 嘉祥县| 渑池县| 台东县| 响水县| 祁连县| 安义县| 视频| 甘南县| 绥江县| 澎湖县| 天津市| 建阳市| 凤翔县| 高尔夫| 囊谦县| 任丘市| 丰原市| 通河县| 深州市| 丹凤县| 竹山县| 黑河市| 集安市| 景泰县| 斗六市| 东莞市| 响水县| 漾濞| 宜章县| 富锦市| 拉萨市| 安溪县|