什么:
当我为类型为 LocalDate 的字段设置@JsonFormat
->lenient = OptBoolean.FALSE
时,它显示Unable to obtain LocalDate from TemporalAccessor
.jackson
版本为2.11.4
,SpringBoot版本为2.4.2
。
详情:
今天早上我将 SpringBoot 升级到2.4.2
,但是在反序列化类型为 LocalDate 的字段时,我的测试失败了。
这是我的代码:
package com.example.demo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.OptBoolean;
import java.time.LocalDate;
public class Demo {
public Demo(){}
public Demo(LocalDate localDate){
this.localDate = localDate;
}
@JsonFormat(pattern = "yyyy/MM/dd", lenient = OptBoolean.FALSE)
private LocalDate localDate;
public LocalDate getLocalDate() {
return localDate;
}
public void setLocalDate(LocalDate localDate) {
this.localDate = localDate;
}
}
package com.example.demo;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class Controller {
@GetMapping("/test")
public ResponseEntity<String> test(@RequestBody Demo demo) {
var localDate = demo.getLocalDate().toString();
return ResponseEntity.ok(localDate);
}
}
什么时候
curl -L -X GET 'http://localhost:8080/test'
-H 'Content-Type: application/json'
--data-raw '{
"localDate": "2020/01/15"
}'
它显示
Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `java.time.LocalDate` from String "2020/01/15": Failed to deserialize java.time.LocalDate: (java.time.format.DateTimeParseException) Text '2020/01/15' could not be parsed: Unable to obtain LocalDate from TemporalAccessor: {YearOfEra=2020, MonthOfYear=1, DayOfMonth=15},ISO of type java.time.format.Parsed; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.time.LocalDate` from String "2020/01/15": Failed to deserialize java.time.LocalDate: (java.time.format.DateTimeParseException) Text '2020/01/15' could not be parsed: Unable to obtain LocalDate from TemporalAccessor: {YearOfEra=2020, MonthOfYear=1, DayOfMonth=15},ISO of type java.time.format.Parsed
at [Source: (PushbackInputStream); line: 2, column: 18] (through reference chain: com.example.demo.Demo["localDate"])]
但是当我将lenient
设置为TRUE
或删除注释时,它运行良好。
有谁知道真正的原因?
我得到了答案。
当我们设置lenient = OptBoolean.FALSE
时,它将使用严格模式进行DateTimeFormatter
。请参阅问题 jackson-modules-java8 #199 和 jackson-modules-java8 #199。
错误显示Unable to obtain LocalDate from TemporalAccessor: {YearOfEra=2020, MonthOfYear=1, DayOfMonth=15}
.
在java8java.time.format.DateTimeFormatter
中,这里有3行注释:
Symbol Meaning Presentation Examples
------ ------- ------------ -------
G era text AD; Anno Domini; A
u year year 2004; 04
y year-of-era year 2004; 04
它说y
意味着时代年份,u
实际表示年份。
因此,将模式yyyy-MM-dd
更新为uuuu-MM-dd
,它有效。
而如果你想在模式中使用y
,最好G
一起使用来具体时代。
请参阅问题:https://github.com/FasterXML/jackson-modules-java8/issues/199