无法从 String 值实例化 [简单类型,类 java.time.LocalDate] 类型的值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36953090/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can not instantiate value of type [simple type, class java.time.LocalDate] from String value
提问by Jeff
I have a class like this:
我有一个这样的课程:
@Data
@NoArgsConstructor(force = true)
@AllArgsConstructor(staticName = "of")
public class BusinessPeriodDTO {
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
LocalDate startDate;
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
LocalDate endDate;
}
And I used this class inside another class, let's call it PurchaseOrder
我在另一个类中使用了这个类,我们称之为 PurchaseOrder
@Entity
@Data
@NoArgsConstructor(access = AccessLevel.PROTECTED, force = true)
public class PurchaseOrder {
@EmbeddedId
PurchaseOrderID id;
@Embedded
BusinessPeriod rentalPeriod;
public static PurchaseOrder of(PurchaseOrderID id, BusinessPeriod period) {
PurchaseOrder po = new PurchaseOrder();
po.id = id;
po.rentalPeriod = period;
return po;
}
And I'm trying to populate a purchaseOrder record using jakson and this JSON:
我正在尝试使用 jakson 和这个 JSON 填充 purchaseOrder 记录:
{
"_class": "com.rentit.sales.domain.model.PurchaseOrder",
"id": 1,
"rentalPeriod": {
"startDate": "2016-10-10",
"endDate": "2016-12-12"
}
}
But I have faced with an error:
但是我遇到了一个错误:
java.lang.RuntimeException: com.fasterxml.Hymanson.databind.JsonMappingException: Can not instantiate value of type [simple type, class java.time.LocalDate] from String value ('2016-10-10');
java.lang.RuntimeException:com.fasterxml.Hymanson.databind.JsonMappingException:无法从字符串值('2016-10-10')实例化[简单类型,类java.time.LocalDate]类型的值;
I am sure jakson and popularization works correctly.
我确信 jakson 和大众化工作正常。
回答by Luca Tampellini
Include in your pom.xml:
包括在你的 pom.xml 中:
<dependency>
<groupId>com.fasterxml.Hymanson.datatype</groupId>
<artifactId>Hymanson-datatype-jsr310</artifactId>
<version>2.9.6</version>
</dependency>
Then in your BusinessPeriodDTO.java
import LocalDateDeserializer
as follows:
然后在你的BusinessPeriodDTO.java
导入LocalDateDeserializer
如下:
import com.fasterxml.Hymanson.datatype.jsr310.deser.LocalDateDeserializer;
And finally, always in your BusinessPeriodDTO.java
file, annotate the interested dates like this:
最后,始终在您的BusinessPeriodDTO.java
文件中,像这样注释感兴趣的日期:
@JsonDeserialize(using = LocalDateDeserializer.class)
LocalDate startDate;
@JsonDeserialize(using = LocalDateDeserializer.class)
LocalDate endDate;
回答by vanOekel
Old question but I recently had to answer it for myself.
There are different solutions (as commented by rapasoft, see for example here).
The quick solution I used involves adding a setDate(String)
method for deserialization.
It might not be the prettiest solution, but it works without updating other classes.
Below a runnable class to demonstrate:
老问题,但我最近不得不自己回答。有不同的解决方案(如 rapasoft 所评论的,请参见此处的示例)。我使用的快速解决方案涉及添加setDate(String)
反序列化方法。它可能不是最漂亮的解决方案,但它无需更新其他类即可工作。下面有一个可运行的类来演示:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import com.fasterxml.Hymanson.annotation.JsonFormat;
import com.fasterxml.Hymanson.annotation.JsonFormat.Shape;
import com.fasterxml.Hymanson.databind.ObjectMapper;
import com.fasterxml.Hymanson.datatype.jsr310.JavaTimeModule;
/**
* Demonstrate Java 8 date/time (de)serialization for JSON with Hymanson databind.
* Requires {@code com.fasterxml.Hymanson.core:Hymanson-databind:2.8.5}
* and {@code com.fasterxml.Hymanson.datatype:Hymanson-datatype-jsr310:2.8.5}
*/
public class JdateDto {
/** The pattern as specified by {@link java.text.SimpleDateFormat} */
public static final String ISO_LOCAL_DATE_PATTERN = "yyyy-MM-dd";
/* Used when serializing isoLocalDate. */
@JsonFormat(shape = Shape.STRING, pattern = ISO_LOCAL_DATE_PATTERN)
private LocalDate isoLocalDate;
public LocalDate getIsoLocalDate() {
return isoLocalDate;
}
/* Used when deserializing isoLocalDate. */
public void setIsoLocalDate(String date) {
setIsoLocalDate(LocalDate.parse(date, DateTimeFormatter.ISO_LOCAL_DATE));
}
public void setIsoLocalDate(LocalDate isoDate) {
this.isoLocalDate = isoDate;
}
public static void main(String[] args) {
try {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
JdateDto dto = new JdateDto();
dto.setIsoLocalDate(LocalDate.now());
String json = mapper.writeValueAsString(dto);
System.out.println(json);
JdateDto dto2 = mapper.readValue(json, JdateDto.class);
if (dto.getIsoLocalDate().equals(dto2.getIsoLocalDate())) {
System.out.println("Dates match.");
} else {
System.out.println("Dates do not match!");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}