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>
820   6  

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

    Ничего не найдено.