Привязка данных Джексона для LocalDate [] с использованием аннотации - PullRequest
0 голосов
/ 25 ноября 2018

Я конвертирую файл JSON в объект Java с помощью Jackson with Java 8 Module.Но при преобразовании массива 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)

Ответы [ 3 ]

0 голосов
/ 25 ноября 2018

Я подозреваю, что, глядя на ваш код и вашу модель json, он пытается преобразовать в массив, используя десериализатор, определенный для одного объекта.Проще говоря, вы пытаетесь преобразовать один элемент в массив, который он не может проанализировать.Вместо этого вы можете попробовать список LocalDate.Что-то вроде:

List<LocalDate> skip;

Возможно, вам даже потребуется создать собственный десериализатор на основе сериализатора даты.

0 голосов
/ 25 ноября 2018

Поскольку skip имеет тип массив , LocalDateSerializer, LocalDateDeserializer и JsonFormat не работают "из коробки" - они реализованы так, чтобы ожидать токены прямого значения, а не массивы.

Вы можете реализовать свой собственный сериализатор / десериализатор.Наивный десериализатор, который я реализовал для десериализации вашего примера, выглядит следующим образом:

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 и так далее, если вы считаете, что это стоит затраченных усилий.

0 голосов
/ 25 ноября 2018

Просто на первый взгляд: на самом деле объекты json находятся в вашем массиве json или просто строки, как вы показали?Это должно быть примерно так: {"skip": ["key1": "01/01/2019", "key2": "26/01/2019"]}

...