Я никогда не мог заставить это работать просто, используя аннотации. Чтобы заставить его работать, я создал ContextResolver
for ObjectMapper
, затем добавил JSR310Module
( update: теперь оно JavaTimeModule
взято ) вместе с еще одним предупреждением, которое было необходимо для установки write-date-as-timestamp в false. Подробнее смотрите в документации по модулю JSR310 . Вот пример того, что я использовал.
зависимость
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.4.0</version>
</dependency>
Примечание. Одна проблема, с которой я столкнулся, заключается в том, что jackson-annotation
версия, загруженная другой зависимостью, использует версию 2.3.2, которая отменяет версию 2.4, требуемую для jsr310
. Я получил NoClassDefFound для ObjectIdResolver
класса 2.4. Так что мне просто нужно выстроить включенные версии зависимостей
ContextResolver
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JSR310Module;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
@Provider
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {
private final ObjectMapper MAPPER;
public ObjectMapperContextResolver() {
MAPPER = new ObjectMapper();
// Now you should use JavaTimeModule instead
MAPPER.registerModule(new JSR310Module());
MAPPER.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
}
@Override
public ObjectMapper getContext(Class<?> type) {
return MAPPER;
}
}
Ресурсный класс
@Path("person")
public class LocalDateResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getPerson() {
Person person = new Person();
person.birthDate = LocalDate.now();
return Response.ok(person).build();
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response createPerson(Person person) {
return Response.ok(
DateTimeFormatter.ISO_DATE.format(person.birthDate)).build();
}
public static class Person {
public LocalDate birthDate;
}
}
Тест
curl -v http://localhost:8080/api/person
Результат: {"birthDate":"2015-03-01"}
curl -v -POST -H "Content-Type:application/json" -d "{\"birthDate\":\"2015-03-01\"}" http://localhost:8080/api/person
Результат: 2015-03-01
Смотрите также здесь для решения JAXB.
ОБНОВИТЬ
JSR310Module
Нежелателен версии 2.7 Джексона. Вместо этого вы должны зарегистрировать модуль JavaTimeModule
. Это все та же зависимость.
getContext
метод. Если этот метод вызывается, я не вижу причин для этого не работать. Если он не вызывается, это может быть что-то, что должно быть исправлено в конфигурации приложения. Для этого мне нужно увидеть больше, чем вы предоставили. Как и версия Resteasy, зависимости, конфигурация приложения либо web.xml, либо подкласс приложения. В основном достаточно, чтобы воспроизвести проблемуObjectMapper
как swagger (вы можете увидеть ссылку в вопросе). Я не знаю, так как я не много работаю с чванством. Но я думаю, что чванство - главная проблема, почему не вызывается contextresolver.@JsonSerialize и @JsonDeserialize отлично работали для меня. Они устраняют необходимость импортировать дополнительный модуль jsr310:
десериализатор:
Serializer:
источник
jackson-datatype-jsr310
. Нет необходимости вручную определять их в вашем проекте.jackson-datatype-jsr310
.у меня отлично работает
источник
new com.fasterxml.jackson.datatype.jsr310.JSR310Module()
для версии 2.5.4 Джексона. Класс JavaTimeModule в этой версии не существует.LocalDateTime
(Джексон 2.9.5). Требуется 1 дополнительная зависимость, поэтому мой build.sbt выглядит так:"com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.9.5", "com.fasterxml.jackson.datatype" % "jackson-datatype-jsr310" % "2.9.5"
В веб-приложении Spring Boot с версией Jackson и JSR 310 "2.8.5"
В
@JsonFormat
работе:источник
@JsonDeserialize(using= LocalDateDeserializer.class)
@JsonFormat
просто для изменения формата выходных данных. stackoverflow.com/a/53251526/816759 отлично работает с@JsonFormat
,@JsonDeserialize
,@JsonSerialize
spring.jackson.serialization.write-dates-as-timestamps=false
в ваш файлapplication.properties
, и онyyyy-MM-dd
автоматически форматирует его . Нет необходимости@JsonFormat
Самым простым решением (которое также поддерживает десериализацию и сериализацию) является
При использовании следующих зависимостей в вашем проекте.
специалист
Gradle
Никакой дополнительной реализации ContextResolver, Serializer или Deserializer не требуется.
источник
ObjectMapper
неJavaTimeModule
зарегистрировались. Если ваш экземпляр ObjectMapper предоставлен из инфраструктуры spring / MessageConverter. Они сотворили магию, чтобы соединить их. В противном случае следуетregisterModule
включитьLocalDateDeserializer
по умолчанию для всех «LocalDate» в POJOПоскольку
LocalDateSerializer
по умолчанию он превращается в «[год, месяц, день]» (массив json), а не в «год-месяц-день» (строка json), и поскольку я не хочу требовать какой-либо специальнойObjectMapper
настройки (вы можете makeLocalDateSerializer
generate strings, если вы отключите,SerializationFeature.WRITE_DATES_AS_TIMESTAMPS
но для этого потребуется дополнительная настройкаObjectMapper
), я использую следующее:импорт:
код:
И теперь я могу просто
new ObjectMapper()
читать и писать свои объекты без какой-либо специальной настройки.источник
"2018-12-07"
вместо этого"2018-12-7"
вы получите ошибку.yyyy-MM-dd
форматом (2 цифры месяца и дня), а неyyyy-M-d
(1 цифра месяца или дня).Просто обновление ответа Кристофера.
Поскольку версия 2.6.0
Используйте JavaTimeModule вместо JSR310Module (устарело).
Согласно документации , новый JavaTimeModule использует те же стандартные настройки по умолчанию для сериализации, которая НЕ использует идентификаторы часовых поясов, а вместо этого использует только смещения часовых поясов, совместимые с ISO-8601.
Поведение можно изменить с помощью SerializationFeature.WRITE_DATES_WITH_ZONE_ID
источник
MAPPER.registerModule(new JavaTimeModule());
строку. Это позволило мне отформатировать объекты LocalDate в формате «2020-02-20».MAPPER.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
Линия мне не нужна, то , что я искалСледующая аннотация сработала для меня.
Никаких дополнительных зависимостей не требуется.
источник
источник
https://stackoverflow.com/a/53251526/1282532 - самый простой способ сериализации / десериализации свойства. У меня есть два опасения относительно этого подхода - до некоторой степени нарушение принципа DRY и высокая степень связи между pojo и mapper.
Если у вас есть POJO с несколькими полями LocalDate, лучше настроить mapper вместо POJO. Это может быть так же просто, как https://stackoverflow.com/a/35062824/1282532 если вы используете значения ISO-8601 («2019-01-31»).
Если вам нужно обрабатывать нестандартный формат, код будет таким:
Логика написана только один раз, ее можно повторно использовать для нескольких POJO
источник
Самый простой и самый короткий:
при загрузке Spring> = 2.2+ зависимость не требуется
источник
Начиная с 2020 и Jackson 2.10.1 нет необходимости в каком-либо специальном коде, просто нужно сказать Джексону, что вы хотите:
Об этом уже упоминалось в этом ответе , я добавляю модульный тест, проверяющий функциональность:
TestBean использует Lombok для создания шаблона для bean-компонента.
источник
В классе конфигурации определяют LocalDateSerializer и LocalDateDeserializer класс и зарегистрировать их в ObjectMapper через JavaTimeModule , как показано ниже:
источник
Если ваш запрос содержит такой объект:
Тогда вы можете использовать:
Над полем:
Код находится на Kotlin, но, конечно, это сработает и для Java.
источник