Невозможно отключить LocalDate и класс LocalTime с помощью Jackson

#java #json #akka #unmarshalling #akka-http

#java #json #akka #отмена сопоставлений #akka-http

Вопрос:

Я создаю POST-маршрут с помощью akka, где я десериализирую свои Json-данные в Video object, но следующий запрос curl:

 curl -H "Content-Type: application/json" -X POST -d '{"title": "Video Title","videoDate":"10-2-2018","videoTime":"12:10:11"}' http://localhost:9090/updatedData
  

выдает ошибку: Cannot unmarshal JSON as Video

Запрос работает нормально, когда я удаляю поля videoDate и videoTime из json.

Jackson.unmarshaller(VideoInfo.class)

 //Video.class
public class Video {
    private String title;
    private LocalDate videoDate;
    private LocalTime videoTime;
}
  

Используемая зависимость maven является

 <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.8</version>
</dependency>
  

Вот мой маршрут / обновлеНные данные

 post(() ->
      path("updatedData", () -> {
          LOGGER.info("calling POST /updatedData");
          return entity(Jackson.unmarshaller(Video.class), videoInfo -> {
              LOGGER.debug("Payload received : "   videoInfo.toString());
              ArrayList<HttpHeader> headers = getCORSHeaders();
              return respondWithHeaders(headers, () ->
                                        onSuccess(videoFrameProcessing.updateVideoInfo(videoInfo), this::complete));
                            });
                        })),
  

Комментарии:

1. Пожалуйста, опубликуйте полный список исключений stacktrace, а также какие зависимости Jackson вы используете (для поддержки LocalDate и LocalTime требуется зависимость jackson-datatype-jsr310).

2. Формат ISO для LocalDate будет 2018-02-10 (если 2 — это месяц в вашем примере).

3. Смотрите ответ, вам нужно добавить этот модуль Java 8 Time API. Также проблемой может быть формат.

4. @MarkRotteveel Я получаю информацию об ошибке, отправляя запрос curl на маршруте.

Ответ №1:

Джексону требуется дополнительный модуль для Java 8 Time API.
Модуль

 jackson-datatype-jsr310
  

был устаревшим и теперь является частью

 jackson-modules-java8
  

 <dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.9.8</version>
</dependency>
  

Это означает, что вам нужно зарегистрировать этот модуль вручную

 final ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
  

Jackson Класс Akka предлагает перегруженную версию unmarshaller , которую вы можете использовать для передачи настроенной версии ObjectMapper

 public static <T> Unmarshaller<HttpEntity, T> unmarshaller(ObjectMapper mapper, Class<T> expectedType) {
  return Unmarshaller.forMediaType(MediaTypes.APPLICATION_JSON, Unmarshaller.entityToString())
                     .thenApply(s -> fromJSON(mapper, s, expectedType));
}
  

Итак, вместо

 Jackson.unmarshaller(Video.class)
  

использовать

 Jackson.unmarshaller(objectMapper, Video.class);
  

objectMapper Параметр является пользовательским ObjectMapper

 final ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
  

Полный фрагмент будет

 post(() ->
   path("updatedData", () -> {
      LOGGER.info("calling POST /updatedData");

      final ObjectMapper objectMapper = new ObjectMapper();
      objectMapper.registerModule(new JavaTimeModule());

      return entity(Jackson.unmarshaller(objectMapper, Video.class), videoInfo -> {
          LOGGER.debug("Payload received : "   videoInfo.toString());
          ArrayList<HttpHeader> headers = getCORSHeaders();
          return respondWithHeaders(headers, () ->
                       onSuccess(videoFrameProcessing.updateVideoInfo(videoInfo), this::complete));
     });
 })),
  

Очевидно, что извлеките ObjectMapper как «глобальную» переменную.

Комментарии:

1. Раньше я не использовал ни один object mapper. Пожалуйста, скажите мне, как действовать с object mapper, поскольку я всего лишь новичок в выполнении сопоставления.

2. @Yatharth7 можете ли вы опубликовать код, который десериализует ответ? Или это просто вызов CURL?

3. Это просто вызов curl.

4. @Yatharth7 и что это за «Jackson.unmarshaller(VideoInfo.class )» в вашем вопросе?

5. Это маршрут, я добавил, о котором идет речь сейчас