У меня есть JSON REST API с конечной точкой POST /items
, которая ожидает такой объект, как:
{"name": "item_name", "timestamp": "2018-01-01T01:01:01.001"}
Мне нужно вызвать эту конечную точку из приложения JEE7, развернутого на WildFly10.
Для моделирования объекта в Java я определил простой класс DTO:
class ItemDTO {
private String name;
private LocalDateTime timestamp;
// default constructor and getters/setters omitted for brevity
}
По умолчанию сериализация LocalDateTime приводит к сложному объекту JSON вместо строки ISO8601.
Следуя тому, что я нашел в Интернете, я добавил к своим зависимостям:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>${jackson.version}</version>
</dependency>
С jackson.version = 2.7.4
ClientBuilder builder = ClientBuilder.newBuilder()
.register(new RequestLogger())
.register(
new JacksonJsonProvider(
new ObjectMapper()
.registerModule(new JavaTimeModule())
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS, false)
.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"))
, DEFAULT_ANNOTATIONS)
);
Приведенный выше код настраивает clientBuilder для создания клиентов, оснащенных ObjectMapper, который будет сериализовывать типы даты / времени Java8 в строки ISO8601.
Response creation = builder.build()
.target("http://localhost:8080/my-api/v1.0/items")
.request().accept(MediaType.APPLICATION_JSON)
.post(Entity.entity(itemDTO, MediaType.APPLICATION_JSON));
Неожиданно этот запрос завершается ошибкой , так как LocalDateTime
, содержащийся в ItemDTO
, все еще сериализуется в сложный объект JSON.
N.B .: Мой REST API вполне способен десериализовать строку ISO8601 в LocalDateTime
N.B .: код, создающий запрос POST, работает отлично, если не выполняется внутри контейнера (т.е. LocalDateTime сериализуется в ISO8601)