Java 8 LocalDate Jackson-Format

Für java.util.Date wenn ich es tue

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy") private Date dateOfBirth; 

dann in JSON Anfrage wenn ich sende

 { {"dateOfBirth":"01/01/2000"} } 

Es klappt.

Wie sollte ich dies für das LocalDate- Feld von Java 8 tun ?

Ich habe es versucht

 @JsonDeserialize(using = LocalDateDeserializer.class) @JsonSerialize(using = LocalDateSerializer.class) private LocalDate dateOfBirth; 

Es hat nicht funktioniert.

Kann mir bitte jemand sagen, was der richtige Weg ist.

Unten sind Abhängigkeiten

  org.jboss.resteasy jaxrs-api 3.0.9.Final   com.fasterxml.jackson.jaxrs jackson-jaxrs-json-provider 2.4.2   com.wordnik swagger-annotations 1.3.10   

    Mit Annotationen konnte ich das nie so einfach machen. Um es zum ContextResolver zu bringen, erstellte ich einen ContextResolver für ContextResolver , dann fügte ich das JSR310Module hinzu, zusammen mit einem weiteren Vorbehalt, der darin bestand, write-date-as-timestamp auf false zu setzen. Weitere Informationen finden Sie in der Dokumentation zum JSR310-Modul . Hier ist ein Beispiel von dem, was ich benutzt habe.

    Abhängigkeit

      com.fasterxml.jackson.datatype jackson-datatype-jsr310 2.4.0  

    Hinweis: Ein Problem, mit dem ich konfrontiert war, ist, dass die Version von jackson-annotation die von einer anderen Abhängigkeit herangezogen wurde, die Version 2.3.2 verwendet hat, die die vom jsr310 benötigte 2.4 jsr310 . Was passiert ist, ist, dass ich NoClassDefFound für ObjectIdResolver , was eine class 2.4 ist. Also musste ich nur die enthaltenen Abhängigkeitsversionen anordnen

    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 { 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; } } 

    Ressourcenklasse

     @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; } } 

    Prüfung

    curl -v http://localhost:8080/api/person
    Ergebnis: {"birthDate":"2015-03-01"}

    curl -v -POST -H "Content-Type:application/json" -d "{\"birthDate\":\"2015-03-01\"}" http://localhost:8080/api/person
    Ergebnis: 2015-03-01


    Siehe auch hier für JAXB-Lösung.

    AKTUALISIEREN

    Das JSR310Module ist ab Version 2.7 von Jackson veraltet. Stattdessen sollten Sie das Modul JavaTimeModule registrieren. Es ist immer noch die gleiche Abhängigkeit.

    @ JsonSerialize und @JsonDeserialize funktionierte gut für mich. Sie müssen das zusätzliche Modul jsr310 nicht mehr importieren:

     @JsonDeserialize(using = LocalDateDeserializer.class) @JsonSerialize(using = LocalDateSerializer.class) private LocalDate dateOfBirth; 

    Deserializer:

     public class LocalDateDeserializer extends StdDeserializer { 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)); } } 

    Serializer:

     public class LocalDateSerializer extends StdSerializer { 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)); } } 

    Im Spring Boot-Web-App, mit “jackson” und “jsr310” Version “2.8.5”

     compile "com.fasterxml.jackson.core:jackson-databind:2.8.5" runtime "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.8.5" 

    Das @JsonFormat funktioniert:

     import com.fasterxml.jackson.annotation.JsonFormat; @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") private LocalDate birthDate; 
      ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JavaTimeModule()); mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); 

    funktioniert gut für mich.

    Nur ein Update von Christopher Antwort.

    Seit der Version 2.6.0

      com.fasterxml.jackson.datatype jackson-datatype-jsr310 2.9.0  

    Verwenden Sie JavaTimeModule anstelle von JSR310Module (veraltet).

     @Provider public class ObjectMapperContextResolver implements ContextResolver { 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; } } 

    Gemäß der Dokumentation verwendet das neue JavaTimeModule die gleichen Standardeinstellungen wie die Serialisierung, die keine Timezone-IDs verwendet und stattdessen nur ISO-8601-konforme Timezone-Offsets verwendet.

    Das Verhalten kann mithilfe von SerializationFeature.WRITE_DATES_WITH_ZONE_ID geändert werden

    Da LocalDateSerializer es LocalDateSerializer “[Jahr, Monat, Tag]” (ein JSON-Array) anstelle von “Jahr-Monat-Tag” (eine JSON-Zeichenfolge) einstellt, und da ich kein spezielles ObjectMapper Setup benötigen möchte ( Wenn LocalDateSerializer Strings generiert, wenn Sie SerializationFeature.WRITE_DATES_AS_TIMESTAMPS deaktivieren, aber eine zusätzliche Einrichtung für Ihren LocalDateSerializer erfordert), verwende ich Folgendes:

    Importe:

     import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; 

    Code:

     // generates "yyyy-MM-dd" output @JsonSerialize(using = ToStringSerializer.class) // handles "yyyy-MM-dd" input just fine @JsonDeserialize(using = LocalDateDeserializer.class) private LocalDate localDate; 

    Und jetzt kann ich einfach den new ObjectMapper() , um meine Objekte ohne spezielle Einstellungen zu lesen und zu schreiben.