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

Springcloud?feign傳日期類型參數(shù)報(bào)錯(cuò)的解決方案

 更新時(shí)間:2022年03月14日 15:40:41   作者:weixin_33725126  
這篇文章主要介紹了Springcloud?feign傳日期類型參數(shù)報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

feign傳日期類型參數(shù)報(bào)錯(cuò)

Date類型參數(shù)報(bào)錯(cuò)

在Spring cloud feign接口中傳遞Date類型參數(shù)時(shí)報(bào)錯(cuò),報(bào)錯(cuò)信息。

場(chǎng)景:

客戶端傳遞一個(gè)new Date()的參數(shù),服務(wù)端接受的參數(shù)和客戶端有時(shí)間差。

客戶端打印格式化的new Date():

2018-05-11 10:23:36

而服務(wù)端接收到的參數(shù)是:

2018-05-12 00:23:36

我們從Feign啟動(dòng)的源碼可以看出,F(xiàn)eign在encode和decode時(shí)會(huì)用SpringEncoder類來(lái)實(shí)現(xiàn):

? ? @Bean
? ? @ConditionalOnMissingBean
? ? public Decoder feignDecoder() {
? ? ? ? return new ResponseEntityDecoder(new SpringDecoder(this.messageConverters));
? ? }
?
? ? @Bean
? ? @ConditionalOnMissingBean
? ? public Encoder feignEncoder() {
? ? ? ? return new SpringEncoder(this.messageConverters);
? ? }

而SpringEncoder的HttpMessageConverters使用的是Jackson默認(rèn)模板,該模板來(lái)自基類WebMvcConfigurationSupport.java:

? ? protected final List<HttpMessageConverter<?>> getMessageConverters() {
? ? ? ? if (this.messageConverters == null) {
? ? ? ? ? ? this.messageConverters = new ArrayList<HttpMessageConverter<?>>();
? ? ? ? ? ? configureMessageConverters(this.messageConverters);
? ? ? ? ? ? if (this.messageConverters.isEmpty()) {
? ? ? ? ? ? ? ? addDefaultHttpMessageConverters(this.messageConverters);
? ? ? ? ? ? }
? ? ? ? ? ? extendMessageConverters(this.messageConverters);
? ? ? ? }
? ? ? ? return this.messageConverters;
? ? }

而WebMvcConfigurationSupport.java最終使用的是默認(rèn)的ObjectMapper生成的MappingJackson2HttpMessageConverter。

至此可以看出該問(wèn)題的產(chǎn)生并不是Feign的問(wèn)題,而是Feign實(shí)現(xiàn)中使用的Spring MVC中的Jackson轉(zhuǎn)換參數(shù)問(wèn)題,默認(rèn)的TimeZone并不是東八區(qū),而是UTC。

? ? /**
? ? ?* Override the default {@link TimeZone} to use for formatting.
? ? ?* Default value used is UTC (NOT local timezone).
? ? ?* @since 4.1.5
? ? ?*/
? ? public Jackson2ObjectMapperBuilder timeZone(TimeZone timeZone) {
? ? ? ? this.timeZone = timeZone;
? ? ? ? return this;
? ? }

這個(gè)問(wèn)題,在Spring MVC中可以在接口或者字段上添加注解來(lái)解決,但在Feign中使用GET請(qǐng)求的接口添加注解是不行的。debug發(fā)現(xiàn),Spring MVC在處理Date的時(shí)候,調(diào)用了sun.reflect.ConstructorAccessor#newInstance(Object[] var1),時(shí)間會(huì)加14個(gè)小時(shí)。具體實(shí)現(xiàn)沒(méi)看到源碼,后續(xù)再研究。需要說(shuō)明的是,加JsonFormat注解對(duì)于Feign接口沒(méi)生效,但Spring MVC是可以的。

OK,回到正題。要解決這個(gè)問(wèn)題,最好的辦法是自定義ObjectMapper。即使是加了注解可以解決問(wèn)題,也依然推薦使用自定義ObjectMapper,因?yàn)榇罅康慕涌诿總€(gè)都添加注解太繁瑣了。

? ? @Bean
? ? @Primary
? ? public ObjectMapper objectMapper() {
? ? ? ? return Jackson2ObjectMapperBuilder.json()
? ? ? ? ? ? ? ? .serializationInclusion(JsonInclude.Include.NON_NULL)
? ? ? ? ? ? ? ? .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
? ? ? ? ? ? ? ? .timeZone(TimeZone.getTimeZone("Asia/Shanghai"))
? ? ? ? ? ? ? ? .build();
? ? }

這樣注解進(jìn)去的ObjectMapper就帶了時(shí)區(qū)。

LocalDate類型報(bào)錯(cuò)

報(bào)錯(cuò)詳情:

Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Can not construct instance of java.time.LocalDate: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of java.time.LocalDate: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)
at [Source: java.io.PushbackInputStream@3ce2b1e2; line: 1, column: 44] (through reference chain: com.chunrun.user.param.UserParams["localDate"])

這是因?yàn)長(zhǎng)ocalDate沒(méi)有提供默認(rèn)的構(gòu)造器,而Jackson還不支持Java8的特征。這時(shí)候只需要加上依賴,ObjectMapper加一行代碼即可:

? ? <dependency>
? ? ? <groupId>com.fasterxml.jackson.datatype</groupId>
? ? ? <artifactId>jackson-datatype-jsr310</artifactId>
? ? ? <version>2.4.0</version>
? ? </dependency>
? ? @Bean
? ? @Primary
? ? public ObjectMapper objectMapper() {
? ? ? ? return Jackson2ObjectMapperBuilder.json()
? ? ? ? ? ? ? ? .serializationInclusion(JsonInclude.Include.NON_NULL)
? ? ? ? ? ? ? ? .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
? ? ? ? ? ? ? ? .timeZone(TimeZone.getTimeZone("Asia/Shanghai"))
? ? ? ? ? ? ? ? .modules(new JSR310Module())
? ? ? ? ? ? ? ? .build();
? ? }

以上配置調(diào)用方也需要。

feign傳參問(wèn)題及傳輸Date類型參數(shù)時(shí)差的坑

feign的調(diào)用如下:

List<LeftSeatCountOfDaysResp> getLeftSeatCountOfDays(
            @RequestParam("configType") Integer configType,
            @RequestParam("courseId") Long courseId,
            @RequestParam("startDateFrom") Date startDateFrom,
            @RequestParam("startDateTo") Date startDateTo,
            @RequestParam("level") Integer level); 

我們采用了兩個(gè)date類型的參數(shù)傳參,結(jié)果:

我們傳入的時(shí)間為:

但服務(wù)端接受到的時(shí)間為:

天啊擼,竟然出現(xiàn)了我們并不熟悉的14h時(shí)差,并不是我們熟悉的8個(gè)小時(shí)。feign真是天坑啊。這是SpringCloud Feign傳Date類型參數(shù)的時(shí)差導(dǎo)致的。

備注:使用date類型傳參,如果是body里面用對(duì)象傳,是不會(huì)出現(xiàn)時(shí)差問(wèn)題的。

下面說(shuō)說(shuō)兩種解決方案

  • 當(dāng)發(fā)送時(shí)間類型時(shí),直接用String發(fā)送(推薦)
  • Feign客戶端實(shí)現(xiàn)FeignFormatterRegistrar接口自定義DateFormatRegister
@Component
    public class DateFormatRegister implements FeignFormatterRegistrar{
        public DateFormatRegister(){
        }
        @Override
        public void registerFormatters(FormatterRegistry registry) {
        registry.addConverter(Date.class, String.class, new Date2StringConverter()); 
        }
        private class Date2StringConverter implements Converter<Date,String>{
            @Override
            public String convert(Date source) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            return sdf.format(source);
            }
        }
    } 

服務(wù)端實(shí)現(xiàn):

@Configuration
    public class WebConfigBeans {
        @Autowired
        private RequestMappingHandlerAdapter handlerAdapter;
        /**
        * 增加字符串轉(zhuǎn)日期的功能
        */
        @PostConstruct
        public void initEditableValidation() {
            ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer) handlerAdapter
                        .getWebBindingInitializer();
            if (initializer.getConversionService() != null) {
                GenericConversionService genericConversionService = (GenericConversionService) initializer
                            .getConversionService();
                genericConversionService.addConverter(String.class, Date.class, new String2DateConverter());
            }
        }
    } 

第二種比較麻煩,但是一勞永逸,代碼的優(yōu)雅性比第一種好。但個(gè)人而言,還是推薦使用第一種。

feign傳參時(shí)候使用@DateTimeFormat注解的坑

@NotNull
    @MyFuture
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date appointDate; //預(yù)定的預(yù)成班日期 

比如這個(gè)字段,服務(wù)端上面用了@DateTimeFormat注解,這樣的話,springMVC手機(jī)支持直接傳字符串2018-03-03自動(dòng)轉(zhuǎn)換的。但是,但是,如果你是用client調(diào)用,那就不報(bào)錯(cuò)啦,報(bào)錯(cuò)啦。所以使用的時(shí)候,一定要注意啊,一定要注意啊。

小結(jié):雖然fiegn有很多坑,但咱不能說(shuō)feign不好用。畢竟他比restTemplate或者h(yuǎn)ttpClient還是優(yōu)雅很多的,能夠簡(jiǎn)化很多東西,負(fù)載均衡也做得不錯(cuò),畢竟在本地就可以做。

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

相關(guān)文章

  • Java實(shí)現(xiàn)打字游戲

    Java實(shí)現(xiàn)打字游戲

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)打字游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • SpringBoot3使用Swagger3的示例詳解

    SpringBoot3使用Swagger3的示例詳解

    本文介紹了如何在Spring Boot 3項(xiàng)目中使用Swagger3進(jìn)行后端接口的前端展示,首先,通過(guò)添加依賴并配置application.yml文件來(lái)快速啟動(dòng)Swagger,然后,詳細(xì)介紹了Swagger3的新注解與Swagger2的區(qū)別,并提供了一些常用注解的使用示例,感興趣的朋友跟隨小編一起看看吧
    2024-11-11
  • Java中File文件操作類的基礎(chǔ)用法

    Java中File文件操作類的基礎(chǔ)用法

    這篇文章主要給大家介紹了關(guān)于Java中File文件操作類基礎(chǔ)用法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用File類具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-07-07
  • springboot集成mybatisplus的方法

    springboot集成mybatisplus的方法

    這篇文章主要為大家詳細(xì)介紹了springboot集成mybatisplus的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • idea項(xiàng)目打開后出現(xiàn)橙色的時(shí)鐘圖標(biāo)的解決

    idea項(xiàng)目打開后出現(xiàn)橙色的時(shí)鐘圖標(biāo)的解決

    本文主要介紹了idea項(xiàng)目打開后出現(xiàn)橙色的時(shí)鐘圖標(biāo)的解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • SpringMVC跨服務(wù)器上傳文件中出現(xiàn)405錯(cuò)誤的解決

    SpringMVC跨服務(wù)器上傳文件中出現(xiàn)405錯(cuò)誤的解決

    這篇文章主要介紹了SpringMVC跨服務(wù)器上傳文件中出現(xiàn)405錯(cuò)誤的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • IDEA運(yùn)行Tomcat中文亂碼出現(xiàn)的各種問(wèn)題

    IDEA運(yùn)行Tomcat中文亂碼出現(xiàn)的各種問(wèn)題

    這篇文章主要介紹了IDEA運(yùn)行Tomcat中文亂碼的各種問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Java實(shí)現(xiàn)簡(jiǎn)單控制臺(tái)版ATM系統(tǒng)

    Java實(shí)現(xiàn)簡(jiǎn)單控制臺(tái)版ATM系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡(jiǎn)單控制臺(tái)版ATM系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • Java多線程開發(fā)工具之CompletableFuture的應(yīng)用詳解

    Java多線程開發(fā)工具之CompletableFuture的應(yīng)用詳解

    做Java編程,難免會(huì)遇到多線程的開發(fā),但是JDK8這個(gè)CompletableFuture類很多開發(fā)者目前還沒(méi)聽說(shuō)過(guò),但是這個(gè)類實(shí)在是太好用了,本文就來(lái)聊聊它的應(yīng)用吧
    2023-03-03
  • Java編程實(shí)現(xiàn)向文本文件中讀取數(shù)據(jù)之Scanner用法示例

    Java編程實(shí)現(xiàn)向文本文件中讀取數(shù)據(jù)之Scanner用法示例

    這篇文章主要介紹了Java編程實(shí)現(xiàn)向文本文件中讀取數(shù)據(jù)之Scanner用法,結(jié)合實(shí)例形式分析了java使用Scanner類讀取文本文件相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下
    2018-03-03

最新評(píng)論

柳林县| 通辽市| 天长市| 南充市| 海门市| 临沧市| 武安市| 乌兰浩特市| 德格县| 和平区| 太仓市| 浠水县| 东阳市| 宜阳县| 无为县| 太康县| 奉化市| 叙永县| 琼结县| 永仁县| 吉林省| 昆明市| 马山县| 长汀县| 嵊州市| 鄯善县| 会东县| 临清市| 夏河县| 内江市| 长丰县| 文化| 班玛县| 宁德市| 黄平县| 东丽区| 永州市| 晋宁县| 大兴区| 吉水县| 尼木县|