#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. Это маршрут, я добавил, о котором идет речь сейчас