Formato do Java 8 LocalDate Jackson

Para java.util.Date quando eu faço

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

então na solicitação JSON quando eu enviar

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

funciona.

Como devo fazer isso para o campo LocalDate do Java 8 ?

Eu tentei ter

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

Não funcionou.

Alguém pode por favor, deixe-me saber qual é o caminho certo para fazer isso ..

Abaixo estão as dependencies

  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   

    Eu nunca consegui fazer isso funcionar de maneira simples usando annotations. Para fazê-lo funcionar, criei um ContextResolver para ObjectMapper , depois adicionei o JSR310Module , juntamente com mais uma advertência, que era a necessidade de definir write-date-as-timestamp como false. Veja mais na documentação do módulo JSR310 . Aqui está um exemplo do que eu usei.

    Dependência

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

    Nota: Um problema que enfrentei é que a versão jackson-annotation jsr310 por outra dependência, usou a versão 2.3.2, que cancelou o 2.4 exigido pelo jsr310 . O que aconteceu foi que eu tenho um NoClassDefFound para ObjectIdResolver , que é uma class 2.4. Então eu só precisava alinhar as versões de dependência incluídas

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

    Classe de recurso

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

    Teste

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

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


    Veja também aqui para solução JAXB.

    ATUALIZAR

    O JSR310Module está obsoleto a partir da versão 2.7 do Jackson. Em vez disso, você deve registrar o módulo JavaTimeModule . Ainda é a mesma dependência.

    @JsonSerialize e @JsonDeserialize funcionaram bem para mim. Eles eliminam a necessidade de importar o módulo jsr310 adicional:

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

    Desserializador:

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

    Serializador:

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

    No aplicativo de boot da web, com ‘jackson’ e ‘jsr310’ versão “2.8.5”

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

    O ‘@JsonFormat’ funciona:

     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); 

    funciona bem para mim.

    Apenas uma atualização da resposta de Christopher.

    Desde a versão 2.6.0

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

    Use o JavaTimeModule em vez de JSR310Module (descontinuado).

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

    De acordo com a documentação , o novo JavaTimeModule usa as mesmas configurações padrão para padronizar a serialização que NÃO usa os IDs de Fuso Horário e, em vez disso, usa somente os deslocamentos do Fuso Horário compatíveis com ISO-8601.

    O comportamento pode ser alterado usando SerializationFeature.WRITE_DATES_WITH_ZONE_ID

    Já que LocalDateSerializer transforma int [[ano, mês, dia] “(um array json) ao invés de” ano-mês-dia “(uma string json) por padrão, e já que eu não quero exigir nenhuma configuração especial do ObjectMapper ( você pode fazer LocalDateSerializer gerar seqüências de caracteres se você desativar SerializationFeature.WRITE_DATES_AS_TIMESTAMPS mas isso requer configuração adicional para seu ObjectMapper ), eu uso o seguinte:

    importações:

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

    código:

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

    E agora eu posso apenas usar o new ObjectMapper() para ler e escrever meus objects sem qualquer configuração especial.