摘要:是開始提供的時(shí)間日期,主要用來(lái)優(yōu)化以前對(duì)于時(shí)間日期的處理操作。然而,我們?cè)谑褂没蚴褂玫臅r(shí)候,往往會(huì)發(fā)現(xiàn)使用請(qǐng)求參數(shù)或返回結(jié)果中有的時(shí)候會(huì)發(fā)生各種問(wèn)題。
LocalDate、LocalTime、LocalDateTime是Java 8開始提供的時(shí)間日期API,主要用來(lái)優(yōu)化Java 8以前對(duì)于時(shí)間日期的處理操作。然而,我們?cè)谑褂肧pring Boot或使用Spring Cloud Feign的時(shí)候,往往會(huì)發(fā)現(xiàn)使用請(qǐng)求參數(shù)或返回結(jié)果中有LocalDate、LocalTime、LocalDateTime的時(shí)候會(huì)發(fā)生各種問(wèn)題。本文我們就來(lái)說(shuō)說(shuō)這種情況下出現(xiàn)的問(wèn)題,以及如何解決。問(wèn)題現(xiàn)象
先來(lái)看看癥狀。比如下面的例子:
@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)建了一個(gè)簡(jiǎn)單的Spring Boot Web應(yīng)用,它提供了一個(gè)提交用戶信息的接口,用戶信息中包含了LocalDate類型的數(shù)據(jù)。此時(shí),如果我們使用Feign來(lái)調(diào)用這個(gè)接口的時(shí)候,會(huì)得到如下錯(cuò)誤:
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"])分析解決
對(duì)于上面的錯(cuò)誤信息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)該馬上就能定位錯(cuò)誤與LocalDate的反序列化有關(guān)。但是,依然會(huì)有很多讀者會(huì)被這段錯(cuò)誤信息java.util.ArrayList[0]->com.didispace.UserDto["birthday"]所困惑。我們命名提交的UserDto["birthday"]是個(gè)LocalDate對(duì)象嘛,跟ArrayList列表對(duì)象有啥關(guān)系呢?
我們不妨通過(guò)postman等手工發(fā)一個(gè)請(qǐng)求看看服務(wù)端返回的是什么?比如你可以按下圖發(fā)起一個(gè)請(qǐng)求:
從上圖中我們就可以理解上面我所提到的困惑了,實(shí)際上默認(rèn)情況下Spring MVC對(duì)于LocalDate序列化成了一個(gè)數(shù)組類型,而Feign在調(diào)用的時(shí)候,還是按照ArrayList來(lái)處理,所以自然無(wú)法反序列化為LocalDate對(duì)象了。
解決方法
為了解決上面的問(wèn)題非常簡(jiǎn)單,因?yàn)閖ackson也為此提供了一整套的序列化方案,我們只需要在pom.xml中引入jackson-datatype-jsr310依賴,具體如下:
com.fasterxml.jackson.datatype jackson-datatype-jsr310
注意:在設(shè)置了spring boot的parent的情況下不需要指定具體的版本,也不建議指定某個(gè)具體版本
在該模塊中封裝對(duì)Java 8的時(shí)間日期API序列化的實(shí)現(xiàn),其具體實(shí)現(xiàn)在這個(gè)類中:com.fasterxml.jackson.datatype.jsr310.JavaTimeModule(注意:一些較早版本瘋轉(zhuǎn)在這個(gè)類中“com.fasterxml.jackson.datatype.jsr310.JSR310Module)。在配置了依賴之后,我們只需要在上面的應(yīng)用主類中增加這個(gè)序列化模塊,同時(shí)開啟標(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í),我們?cè)谠L問(wèn)剛才的接口,就不再是數(shù)組類型了,同時(shí)對(duì)于Feign客戶端的調(diào)用也不會(huì)再出現(xiàn)上面的錯(cuò)誤了。
本文首發(fā):http://blog.didispace.com/Spr...代碼示例
本文的相關(guān)例子可以查看下面?zhèn)}庫(kù)中的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)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/68808.html
摘要:前言前面一篇文章寫了如何安全的使用里面介紹了如何處理日期時(shí)間,以及如何保證線程安全,及其介紹了在中的處理時(shí)間日期默認(rèn)就線程安全的類。引入了全新的日期時(shí)間格式工具,線程安全而且使用方便。 前言 前面一篇文章寫了《SimpleDateFormat 如何安全的使用?》, 里面介紹了 SimpleDateFormat 如何處理日期/時(shí)間,以及如何保證線程安全,及其介紹了在 Java 8 中的處...
摘要:比如,在中,不能將屬性綁定到對(duì)象。引入了新的接口,能夠指出屬性取值的準(zhǔn)確位置。比如,屬性綁定的驗(yàn)證異常現(xiàn)在會(huì)顯示類允許你使用多個(gè)。我們計(jì)劃在中繼續(xù)加強(qiáng)的功能,而第一個(gè)想要支持的功能是不可變屬性綁定。 Spring Boot2.0的屬性綁定 原文從Spring boot第一個(gè)版本以來(lái),我們可以使用@ConfigurationProperties注解將屬性綁定到對(duì)象。也可以指定屬性的各種不...
摘要:處理日期日歷和時(shí)間的不足之處將設(shè)定為可變類型,以及的非線程安全使其應(yīng)用非常受限。最完整的日期時(shí)間,包含時(shí)區(qū)和相對(duì)或格林威治的時(shí)差。獲取當(dāng)前的日期中的用于表示當(dāng)天日期。 簡(jiǎn)介 伴隨 lambda表達(dá)式、streams 以及一系列小優(yōu)化,Java 8 推出了全新的日期時(shí)間API。 Java處理日期、日歷和時(shí)間的不足之處:將 java.util.Date 設(shè)定為可變類型,以及 SimpleD...
摘要:類是一個(gè)抽象類,它為特定瞬間與一組諸如等日歷字段之間的轉(zhuǎn)換提供了一些方法,并為操作日歷字段例如獲得下星期的日期提供了一些方法。是不變的日期時(shí)間對(duì)象代表一個(gè)日期時(shí)間,往往被視為年月日時(shí)分秒。獲得實(shí)例的日期和時(shí)間。 時(shí)區(qū) GMT(Greenwich Mean Time):格林尼治時(shí)間,格林尼治標(biāo)準(zhǔn)時(shí)間的正午是指當(dāng)太陽(yáng)橫穿格林尼治子午線時(shí)(也就是在格林尼治上空最高點(diǎn)時(shí))的時(shí)間。 UTC(U...
摘要:這個(gè)月的天數(shù)是否事閏年似地,一天中的時(shí)間,比如,可以使用類表示。使用靜態(tài)方法,你可以實(shí)現(xiàn)這一目的合并日期和時(shí)間這個(gè)復(fù)合類名叫,是和的合體。對(duì)于最常見(jiàn)的用例,日期和時(shí)間已經(jīng)提供了大量預(yù)定義的。Java的API提供了很多有用的組件,能幫助你構(gòu)建復(fù)雜的應(yīng)用。不過(guò),Java API也不總是完美的。我們相信大多數(shù)有經(jīng)驗(yàn)的程序員都會(huì)贊同Java 8之前的庫(kù)對(duì)日期和時(shí)間的支持就非常不理想。然而,你也不用太...
閱讀 3076·2021-10-14 09:42
閱讀 3318·2019-08-30 15:52
閱讀 3517·2019-08-30 14:02
閱讀 1221·2019-08-29 15:42
閱讀 677·2019-08-29 13:20
閱讀 1243·2019-08-29 12:24
閱讀 571·2019-08-26 10:20
閱讀 753·2019-08-23 18:31