Java 8 LocalDate Jackson формат
на java.утиль.Дата когда я делаю
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy")
private Date dateOfBirth;
затем в запросе JSON, когда я отправляю
{ {"dateOfBirth":"01/01/2000"} }
это работает.
как я должен сделать это для Java 8's LocalDate поле??
Я пыталась
@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
private LocalDate dateOfBirth;
это не сработало.
может кто-то пожалуйста, дайте мне знать, что это правильный способ сделать это..
Ниже приведены зависимости
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>jaxrs-api</artifactId>
<version>3.0.9.Final</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.4.2</version>
</dependency>
<dependency>
<groupId>com.wordnik</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.3.10</version>
</dependency>
<dependency>
6 ответов:
Я никогда не мог заставить это работать просто с помощью аннотаций. Чтобы заставить его работать, я создал
ContextResolverнаObjectMapper, затем я добавилJSR310Module, наряду с еще одним предостережением, которое заключалось в необходимости установить 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(); 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.
обновление
The
JSR310Moduleсчитается устаревшим с версии 2.7 Джексона. Вместо этого, вы должны зарегистрировать модульJavaTimeModule. Это все та же зависимость.
@JsonSerialize и @JsonDeserialize отлично работали для меня. Они исключают необходимость импорта дополнительного модуля jsr310:
@JsonDeserialize(using = LocalDateDeserializer.class) @JsonSerialize(using = LocalDateSerializer.class) private LocalDate dateOfBirth;десериализатор:
public class LocalDateDeserializer extends StdDeserializer<LocalDate> { private static final long serialVersionUID = 1L; protected LocalDateDeserializer() { super(LocalDate.class); } @Override public LocalDate deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { return LocalDate.parse(jp.readValueAs(String.class)); } }сериализатор:
public class LocalDateSerializer extends StdSerializer<LocalDate> { private static final long serialVersionUID = 1L; public LocalDateSerializer(){ super(LocalDate.class); } @Override public void serialize(LocalDate value, JsonGenerator gen, SerializerProvider sp) throws IOException, JsonProcessingException { gen.writeString(value.format(DateTimeFormatter.ISO_LOCAL_DATE)); } }
ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JavaTimeModule()); mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);отлично работает для меня.
в spring boot web app, с' jackson 'и' jsr310 'версии " 2.8.5"
compile "com.fasterxml.jackson.core:jackson-databind:2.8.5" runtime "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.8.5"' @JsonFormat ' работает:
import com.fasterxml.jackson.annotation.JsonFormat; @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") private LocalDate birthDate;
просто обновление ответа Кристофера.
начиная с версии 2.6.0
<dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> <version>2.9.0</version> </dependency>использовать JavaTimeModule вместо JSR310Module (рекомендуется).
@Provider public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> { private final ObjectMapper MAPPER; public ObjectMapperContextResolver() { MAPPER = new ObjectMapper(); MAPPER.registerModule(new JavaTimeModule()); MAPPER.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); } @Override public ObjectMapper getContext(Class<?> type) { return MAPPER; } }по словам документация, новый JavaTimeModule использует те же стандартные настройки по умолчанию для сериализации, которая не использует идентификаторы часовых поясов, а вместо этого использует только ISO-8601 совместимые смещения часовых поясов.
поведение может быть изменено с помощью SerializationFeature.WRITE_DATES_WITH_ZONE_ID
С
LocalDateSerializerпревращает его в "[год, месяц, день] "(массив json), а не" год-месяц-день " (строка json) по умолчанию, и поскольку я не хочу требовать каких-либо специальныхObjectMapperнастройка (можно сделатьLocalDateSerializerгенерировать строки, если отключитьSerializationFeature.WRITE_DATES_AS_TIMESTAMPSно это требует дополнительной настройки на свойObjectMapper), Я использую следующие:импорт:
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;код:
// generates "yyyy-MM-dd" output @JsonSerialize(using = ToStringSerializer.class) // handles "yyyy-MM-dd" input just fine @JsonDeserialize(using = LocalDateDeserializer.class) private LocalDate localDate;и теперь я могу просто использовать
new ObjectMapper()читать и писать мои объекты без каких-либо специальных установка.
Comments