摘要:是開始提供的時間日期,主要用來優(yōu)化以前對于時間日期的處理操作。然而,我們在使用或使用的時候,往往會發(fā)現(xiàn)使用請求參數(shù)或返回結(jié)果中有的時候會發(fā)生各種問題。
LocalDate、LocalTime、LocalDateTime是Java 8開始提供的時間日期API,主要用來優(yōu)化Java 8以前對于時間日期的處理操作。然而,我們在使用Spring Boot或使用Spring Cloud Feign的時候,往往會發(fā)現(xiàn)使用請求參數(shù)或返回結(jié)果中有LocalDate、LocalTime、LocalDateTime的時候會發(fā)生各種問題。本文我們就來說說這種情況下出現(xiàn)的問題,以及如何解決。問題現(xiàn)象
先來看看癥狀。比如下面的例子:
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @RestController class HelloController { @PostMapping("/user") public UserDto user(@RequestBody UserDto userDto) throws Exception { return userDto; } } @Data @NoArgsConstructor @AllArgsConstructor static class UserDto { private String userName; private LocalDate birthday; } }
上面的代碼構(gòu)建了一個簡單的Spring Boot Web應(yīng)用,它提供了一個提交用戶信息的接口,用戶信息中包含了LocalDate類型的數(shù)據(jù)。此時,如果我們使用Feign來調(diào)用這個接口的時候,會得到如下錯誤:
2018-03-13 09:22:58,445 WARN [http-nio-9988-exec-3] org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - 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@67064c65; line: 1, column: 63] (through reference chain: java.util.ArrayList[0]->com.didispace.UserDto["birthday"])分析解決
對于上面的錯誤信息JSON parse error: Can not construct instance of java.time.LocalDate: no suitable constructor found, can not deserialize from Object value,熟悉Spring MVC的童鞋應(yīng)該馬上就能定位錯誤與LocalDate的反序列化有關(guān)。但是,依然會有很多讀者會被這段錯誤信息java.util.ArrayList[0]->com.didispace.UserDto["birthday"]所困惑。我們命名提交的UserDto["birthday"]是個LocalDate對象嘛,跟ArrayList列表對象有啥關(guān)系呢?
我們不妨通過postman等手工發(fā)一個請求看看服務(wù)端返回的是什么?比如你可以按下圖發(fā)起一個請求:
從上圖中我們就可以理解上面我所提到的困惑了,實(shí)際上默認(rèn)情況下Spring MVC對于LocalDate序列化成了一個數(shù)組類型,而Feign在調(diào)用的時候,還是按照ArrayList來處理,所以自然無法反序列化為LocalDate對象了。
解決方法
為了解決上面的問題非常簡單,因?yàn)閖ackson也為此提供了一整套的序列化方案,我們只需要在pom.xml中引入jackson-datatype-jsr310依賴,具體如下:
com.fasterxml.jackson.datatype jackson-datatype-jsr310
注意:在設(shè)置了spring boot的parent的情況下不需要指定具體的版本,也不建議指定某個具體版本
在該模塊中封裝對Java 8的時間日期API序列化的實(shí)現(xiàn),其具體實(shí)現(xiàn)在這個類中:com.fasterxml.jackson.datatype.jsr310.JavaTimeModule(注意:一些較早版本瘋轉(zhuǎn)在這個類中“com.fasterxml.jackson.datatype.jsr310.JSR310Module)。在配置了依賴之后,我們只需要在上面的應(yīng)用主類中增加這個序列化模塊,同時開啟標(biāo)準(zhǔn)的ISO 8601格式:
@Bean public ObjectMapper serializingObjectMapper() { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); objectMapper.registerModule(new JavaTimeModule()); return objectMapper; }
此時,我們在訪問剛才的接口,就不再是數(shù)組類型了,同時對于Feign客戶端的調(diào)用也不會再出現(xiàn)上面的錯誤了。
本文首發(fā):http://blog.didispace.com/Spr...代碼示例
本文的相關(guān)例子可以查看下面?zhèn)}庫中的Chapter3-1-7目錄:
Github:https://github.com/dyc87112/SpringBoot-Learning
Gitee:https://gitee.com/didispace/SpringBoot-Learning
Spring Booot 2.0 新特性詳解正在連載,點(diǎn)擊看看都有哪些解讀
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/68808.html
摘要:前言前面一篇文章寫了如何安全的使用里面介紹了如何處理日期時間,以及如何保證線程安全,及其介紹了在中的處理時間日期默認(rèn)就線程安全的類。引入了全新的日期時間格式工具,線程安全而且使用方便。 前言 前面一篇文章寫了《SimpleDateFormat 如何安全的使用?》, 里面介紹了 SimpleDateFormat 如何處理日期/時間,以及如何保證線程安全,及其介紹了在 Java 8 中的處...
摘要:比如,在中,不能將屬性綁定到對象。引入了新的接口,能夠指出屬性取值的準(zhǔn)確位置。比如,屬性綁定的驗(yàn)證異常現(xiàn)在會顯示類允許你使用多個。我們計劃在中繼續(xù)加強(qiáng)的功能,而第一個想要支持的功能是不可變屬性綁定。 Spring Boot2.0的屬性綁定 原文從Spring boot第一個版本以來,我們可以使用@ConfigurationProperties注解將屬性綁定到對象。也可以指定屬性的各種不...
摘要:處理日期日歷和時間的不足之處將設(shè)定為可變類型,以及的非線程安全使其應(yīng)用非常受限。最完整的日期時間,包含時區(qū)和相對或格林威治的時差。獲取當(dāng)前的日期中的用于表示當(dāng)天日期。 簡介 伴隨 lambda表達(dá)式、streams 以及一系列小優(yōu)化,Java 8 推出了全新的日期時間API。 Java處理日期、日歷和時間的不足之處:將 java.util.Date 設(shè)定為可變類型,以及 SimpleD...
摘要:類是一個抽象類,它為特定瞬間與一組諸如等日歷字段之間的轉(zhuǎn)換提供了一些方法,并為操作日歷字段例如獲得下星期的日期提供了一些方法。是不變的日期時間對象代表一個日期時間,往往被視為年月日時分秒。獲得實(shí)例的日期和時間。 時區(qū) GMT(Greenwich Mean Time):格林尼治時間,格林尼治標(biāo)準(zhǔn)時間的正午是指當(dāng)太陽橫穿格林尼治子午線時(也就是在格林尼治上空最高點(diǎn)時)的時間。 UTC(U...
摘要:這個月的天數(shù)是否事閏年似地,一天中的時間,比如,可以使用類表示。使用靜態(tài)方法,你可以實(shí)現(xiàn)這一目的合并日期和時間這個復(fù)合類名叫,是和的合體。對于最常見的用例,日期和時間已經(jīng)提供了大量預(yù)定義的。Java的API提供了很多有用的組件,能幫助你構(gòu)建復(fù)雜的應(yīng)用。不過,Java API也不總是完美的。我們相信大多數(shù)有經(jīng)驗(yàn)的程序員都會贊同Java 8之前的庫對日期和時間的支持就非常不理想。然而,你也不用太...
閱讀 2856·2021-10-14 09:42
閱讀 3174·2019-08-30 15:52
閱讀 3240·2019-08-30 14:02
閱讀 1102·2019-08-29 15:42
閱讀 529·2019-08-29 13:20
閱讀 1157·2019-08-29 12:24
閱讀 469·2019-08-26 10:20
閱讀 680·2019-08-23 18:31