Jackson 2.11.4 不支持反序列化 LocalDate,在 [@JsonFormat] 中设置 [lenient = OptBoolean.FALSE] 时模式为 [yyyy-MM-dd]?
Jackson 2.11.4 doesn't support deserialize LocalDate which pattern is [yyyy-MM-dd] when set [lenient = OptBoolean.FALSE] in [@JsonFormat]?
内容:
当我为类型为 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 and jackson-modules-java8 #199。
错误显示 Unable to obtain LocalDate from TemporalAccessor: {YearOfEra=2020, MonthOfYear=1, DayOfMonth=15}
。
在java8 java.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
内容:
当我为类型为 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 and jackson-modules-java8 #199。
错误显示 Unable to obtain LocalDate from TemporalAccessor: {YearOfEra=2020, MonthOfYear=1, DayOfMonth=15}
。
在java8 java.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