<meter id="blnnv"></meter>

                  feign請求返回值反序列LocalDateTime異常記錄

                  業界 作者:SegmentFault 2021-07-28 23:54:33

                  作者:linyb極客之路

                  來源:SegmentFault 思否社區

                  前言

                  最近項目組用feign調用遠程服務,消費端報了如下一個異常


                  從異常信息可以得出localdatime反序列化出了異常,而這個異常又是因為jackson無法處理導致。因此我們可以為jackson的ObjectMapper適配一下

                  解決方法

                  1、在pom.xml引入

                  ?<dependency>
                  ????????????????<groupId>com.fasterxml.jackson.datatype</groupId>
                  ????????????????<artifactId>jackson-datatype-jsr310</artifactId>
                  ????????????????<version>${jackson.version}</version>
                  ????????????</dependency>

                  ????????????<dependency>
                  ????????????????<groupId>com.fasterxml.jackson.datatype</groupId>
                  ????????????????<artifactId>jackson-datatype-jdk8</artifactId>
                  ????????????????<version>${jackson.version}</version>
                  ????????????</dependency>

                  注:?jackson-datatype-jsr310這是用來支持jsr310規范的時間,jackson-datatype-jdk8用來支持新的特定于JDK8的類型,例如Optional

                  2、替換默認的ObjectMapper

                  @Configuration
                  public?class?LocalDateTimeConfig??{

                  ????public?static?final?String?DEFAULT_DATE_TIME_FORMAT?=?"yyyy-MM-dd?HH:mm:ss";


                  ??
                  ????@Bean
                  ????public?ObjectMapper?objectMapper()?{
                  ????????ObjectMapper?objectMapper?=?new?ObjectMapper();
                  ????????objectMapper.registerModule(new?Jdk8Module());
                  ????????objectMapper.setDateFormat(new?SimpleDateFormat(DEFAULT_DATE_TIME_FORMAT));
                  ????????objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
                  ????????objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
                  ????????objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
                  ????????objectMapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
                  ????????JavaTimeModule?javaTimeModule?=?new?JavaTimeModule();
                  ????????javaTimeModule.addSerializer(LocalDateTime.class,?new?LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
                  ????????javaTimeModule.addDeserializer(LocalDateTime.class,?new?LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
                  ????????objectMapper.registerModule(javaTimeModule).registerModule(new?ParameterNamesModule());
                  ????????return?objectMapper;
                  ????}

                  疑問點:為什么替換了默認的ObjectMapper后,feign就可以處理LocalDateTime

                  答案就在

                  @Configuration(proxyBeanMethods?=?false)
                  public?class?FeignClientsConfiguration?{

                  ????@Autowired
                  ????private?ObjectFactory<HttpMessageConverters>?messageConverters;


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

                  而messageConverters默認的轉換器是根據HttpMessageConvertersAutoConfiguration而來

                  @Configuration(proxyBeanMethods?=?false)
                  @ConditionalOnClass(HttpMessageConverter.class)
                  @Conditional(NotReactiveWebApplicationCondition.class)
                  @AutoConfigureAfter({?GsonAutoConfiguration.class,?JacksonAutoConfiguration.class,?JsonbAutoConfiguration.class?})
                  @Import({?JacksonHttpMessageConvertersConfiguration.class,?GsonHttpMessageConvertersConfiguration.class,
                  ????????JsonbHttpMessageConvertersConfiguration.class?})
                  public?class?HttpMessageConvertersAutoConfiguration?{

                  ????static?final?String?PREFERRED_MAPPER_PROPERTY?=?"spring.http.converters.preferred-json-mapper";

                  ????@Bean
                  ????@ConditionalOnMissingBean
                  ????public?HttpMessageConverters?messageConverters(ObjectProvider<HttpMessageConverter<?>>?converters)?{
                  ????????return?new?HttpMessageConverters(converters.orderedStream().collect(Collectors.toList()));
                  ????}

                  ObjectProvider具有延遲加載的功能,會根據實際情況加載。springboot的web模塊默認會引入Jackson相關包。官網上有這么一段話


                  這個就說明默認的HttpMessageConverter為MappingJackson2HttpMessageConverter,而MappingJackson2HttpMessageConverter會利用objectMapper來進行序列化和反序列化

                  上面的的話用代碼整理如下

                  public?static?final?String?DEFAULT_DATE_TIME_FORMAT?=?"yyyy-MM-dd?HH:mm:ss";


                  ????@Bean
                  ????public?Decoder?feignDecoder()?{
                  ????????return?new?ResponseEntityDecoder(new?SpringDecoder(messageConverters()));
                  ????}

                  ????public?ObjectFactory<HttpMessageConverters>?messageConverters()?{
                  ????????return?()?->?new?HttpMessageConverters(mappingJackson2HttpMessageConverter());
                  ????}

                  ????public?MappingJackson2HttpMessageConverter?mappingJackson2HttpMessageConverter()?{
                  ????????return?new?MappingJackson2HttpMessageConverter(objectMapper());
                  ????}

                  ????public?ObjectMapper?objectMapper()?{
                  ????????ObjectMapper?objectMapper?=?new?ObjectMapper();
                  ????????objectMapper.registerModule(new?Jdk8Module());
                  ????????objectMapper.setDateFormat(new?SimpleDateFormat(DEFAULT_DATE_TIME_FORMAT));
                  ????????objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
                  ????????objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
                  ????????objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
                  ????????objectMapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
                  ????????JavaTimeModule?javaTimeModule?=?new?JavaTimeModule();
                  ????????javaTimeModule.addSerializer(LocalDateTime.class,?new?LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
                  ????????javaTimeModule.addDeserializer(LocalDateTime.class,?new?LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
                  ????????objectMapper.registerModule(javaTimeModule).registerModule(new?ParameterNamesModule());
                  ????????return?objectMapper;
                  ????}


                  總結

                  異常信息很重要,源碼很重要,官網同樣重要



                  點擊左下角閱讀原文,到?SegmentFault 思否社區?和文章作者展開更多互動和交流,掃描下方”二維碼“或在“公眾號后臺回復“?入群?”即可加入我們的技術交流群,收獲更多的技術文章~

                  -?END -


                  關注公眾號:拾黑(shiheibook)了解更多

                  贊助鏈接:

                  關注數據與安全,洞悉企業級服務市場:https://www.ijiandao.com/
                  四季很好,只要有你,文娛排行榜:https://www.yaopaiming.com/
                  讓資訊觸達的更精準有趣:https://www.0xu.cn/

                  公眾號 關注網絡尖刀微信公眾號
                  隨時掌握互聯網精彩
                  贊助鏈接
                  一级毛片丰满奶头出奶水,国产成人精品午夜福利2010,亚洲欧美激情精品一区二区,色欲av无码蜜臀AV免费播放,夜夜爽夜夜叫夜夜高潮漏水,av无码aV高潮αV喷吹免费,无码vr熟妇人妻AV在线影片