使用注释的 LocalDate[] 的 Jackson 数据绑定
Jackson Data Binding for LocalDate[] using annotation
我正在使用带有 Java 8 模块的 Jackson 将 JSON 文件转换为 Java 对象。但是在将 JSON 数组转换为 LocalDate[] 应用程序时抛出异常。
如何使用注释将下面的 JSON 数组转换为 LocalDate[]?
JSON
{
"skip": [
"01/01/2019",
"26/01/2019"
]
}
代码
@JsonFormat(pattern = "dd/MM/yyyy")
@JsonSerialize(using = LocalDateSerializer.class)
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate[] skip;
异常
com.fasterxml.jackson.databind.exc.MismatchedInputException: Unexpected token (VALUE_STRING) within Array, expected VALUE_NUMBER_INT
at [Source: (ByteArrayInputStream); line: 25, column: 3] (through reference chain: com.saalamsaifi.springwfrlroster.model.Team["skip"])
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1343)
at com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer.deserialize(LocalDateDeserializer.java:110)
at com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer.deserialize(LocalDateDeserializer.java:38)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:127)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3070)
乍一看:您的 json 数组中实际上是 json 个对象,还是如您所示只是字符串?这应该是这样的:
{
"skip": [
"key1":"01/01/2019",
"key2":“2019 年 1 月 26 日”
]
}
我怀疑查看您的代码和您的 json 模型,它正在尝试使用为一个对象定义的反序列化器转换为数组。简单来说,您正在尝试将单个项目转换为它无法解析的数组。您可以改为尝试使用 LocalDate 列表。像这样的东西:
List<LocalDate> skip;
您甚至可能需要基于日期序列化程序创建自己的反序列化程序。
由于 skip
是 array 类型,LocalDateSerializer
、LocalDateDeserializer
和 JsonFormat
不能开箱即用- 它们被实现为期望直接值标记而不是数组。
您可以实现自己的 serializer/deserializers。我为反序列化您的示例而实现的一个简单的反序列化器如下:
public class CustomLocalDateArrayDeserializer extends JsonDeserializer<LocalDate[]> {
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
@Override
public LocalDate[] deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
ArrayList<LocalDate> list = new ArrayList<>();
JsonToken currentToken = p.getCurrentToken();
if (currentToken != JsonToken.START_ARRAY) {
throw new JsonMappingException(p, "Not an array!");
}
currentToken = p.nextToken();
while (currentToken != JsonToken.END_ARRAY) {
if (currentToken != JsonToken.VALUE_STRING) {
throw new JsonMappingException(p, "Not a string element!");
}
LocalDate localDate = LocalDate.parse(p.getValueAsString(), formatter);
list.add(localDate);
currentToken = p.nextToken();
}
return list.toArray(new LocalDate[0]);
}
}
并且我将字段注释更改为 @JsonDeserialize(using = CustomLocalDateArrayDeserializer.class)
。
如果您认为值得付出努力,您可以对其进行迭代和改进,使其阅读并遵守 @JsonFormat
注释等。
我正在使用带有 Java 8 模块的 Jackson 将 JSON 文件转换为 Java 对象。但是在将 JSON 数组转换为 LocalDate[] 应用程序时抛出异常。
如何使用注释将下面的 JSON 数组转换为 LocalDate[]?
JSON
{
"skip": [
"01/01/2019",
"26/01/2019"
]
}
代码
@JsonFormat(pattern = "dd/MM/yyyy")
@JsonSerialize(using = LocalDateSerializer.class)
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate[] skip;
异常
com.fasterxml.jackson.databind.exc.MismatchedInputException: Unexpected token (VALUE_STRING) within Array, expected VALUE_NUMBER_INT
at [Source: (ByteArrayInputStream); line: 25, column: 3] (through reference chain: com.saalamsaifi.springwfrlroster.model.Team["skip"])
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1343)
at com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer.deserialize(LocalDateDeserializer.java:110)
at com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer.deserialize(LocalDateDeserializer.java:38)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:127)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3070)
乍一看:您的 json 数组中实际上是 json 个对象,还是如您所示只是字符串?这应该是这样的: { "skip": [ "key1":"01/01/2019", "key2":“2019 年 1 月 26 日” ] }
我怀疑查看您的代码和您的 json 模型,它正在尝试使用为一个对象定义的反序列化器转换为数组。简单来说,您正在尝试将单个项目转换为它无法解析的数组。您可以改为尝试使用 LocalDate 列表。像这样的东西:
List<LocalDate> skip;
您甚至可能需要基于日期序列化程序创建自己的反序列化程序。
由于 skip
是 array 类型,LocalDateSerializer
、LocalDateDeserializer
和 JsonFormat
不能开箱即用- 它们被实现为期望直接值标记而不是数组。
您可以实现自己的 serializer/deserializers。我为反序列化您的示例而实现的一个简单的反序列化器如下:
public class CustomLocalDateArrayDeserializer extends JsonDeserializer<LocalDate[]> {
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
@Override
public LocalDate[] deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
ArrayList<LocalDate> list = new ArrayList<>();
JsonToken currentToken = p.getCurrentToken();
if (currentToken != JsonToken.START_ARRAY) {
throw new JsonMappingException(p, "Not an array!");
}
currentToken = p.nextToken();
while (currentToken != JsonToken.END_ARRAY) {
if (currentToken != JsonToken.VALUE_STRING) {
throw new JsonMappingException(p, "Not a string element!");
}
LocalDate localDate = LocalDate.parse(p.getValueAsString(), formatter);
list.add(localDate);
currentToken = p.nextToken();
}
return list.toArray(new LocalDate[0]);
}
}
并且我将字段注释更改为 @JsonDeserialize(using = CustomLocalDateArrayDeserializer.class)
。
如果您认为值得付出努力,您可以对其进行迭代和改进,使其阅读并遵守 @JsonFormat
注释等。