Java的8杰克逊LOCALDATE格式Java的8杰克逊LOCALDATE格式(Java 8 Lo

2019-05-10 11:22发布

对于java.util.Date当我做

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

然后在JSON请求时,我送

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

有用。

我应该怎样做到这一点的Java 8的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>

Answer 1:

我从来没有能够得到这个工作使用注释简单。 为了得到它的工作,我创建了一个ContextResolverObjectMapper ,然后我添加了JSR310Module ,多一个警告,这是需要写日期的时间戳设置为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解决方案。

UPDATE

JSR310Module已废弃杰克逊的2.7版本。 相反,你应该注册模块JavaTimeModule 。 它仍然是相同的依赖。



Answer 2:

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


Answer 3:

        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new JavaTimeModule());
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

对我来说工作正常。



Answer 4:

在春季启动Web应用程序,与“杰克逊”和“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;


Answer 5:

(支持反序列化和序列化以及)的简单的解决方案是

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy")
@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
private LocalDate dateOfBirth;

当使用在您的项目下列依赖。

Maven的

<dependency>
   <groupId>com.fasterxml.jackson.core</groupId>
   <artifactId>jackson-databind</artifactId>
   <version>2.9.7</version>
</dependency>
<dependency>
   <groupId>com.fasterxml.jackson.datatype</groupId>
   <artifactId>jackson-datatype-jsr310</artifactId>
   <version>2.9.7</version>
</dependency>

摇篮

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

没有一个ContextResolver的附加执行,串行解串器或需要。



Answer 6:

由于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 (note: "yyyy-M-d" format will not work)
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate localDate;

现在我可以只使用new ObjectMapper()没有任何特殊设置读取和写入我的对象。



Answer 7:

克里斯托弗的回答只是一个更新。

由于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使用相同的标准设置为默认为系列化不使用时区的ID,而是仅使用ISO-8601标准的时区偏移。

行为可以使用SerializationFeature.WRITE_DATES_WITH_ZONE_ID改变



Answer 8:

https://stackoverflow.com/a/53251526/1282532是序列化/反序列化属性的最简单方法。 我有一个关于这个方法有两个担忧 - 高达某一点违反了DRY原则和POJO和映射器之间的高耦合。

public class Trade {
    @JsonFormat(pattern = "yyyyMMdd")
    @JsonDeserialize(using = LocalDateDeserializer.class)
    @JsonSerialize(using = LocalDateSerializer.class)
    private LocalDate tradeDate;
    @JsonFormat(pattern = "yyyyMMdd")
    @JsonDeserialize(using = LocalDateDeserializer.class)
    @JsonSerialize(using = LocalDateSerializer.class)
    private LocalDate maturityDate;
    @JsonFormat(pattern = "yyyyMMdd")
    @JsonDeserialize(using = LocalDateDeserializer.class)
    @JsonSerialize(using = LocalDateSerializer.class)
    private LocalDate entryDate;
}

如果你有多个领域LOCALDATE POJO这是更好地配置映射器,而不是POJO。 它可以是简单如https://stackoverflow.com/a/35062824/1282532如果您使用的ISO-8601的值(“2019年1月31日”)

如果你需要处理自定义格式的代码将是这样的:

ObjectMapper mapper = new ObjectMapper();
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyyMMdd")));
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyyMMdd")));
mapper.registerModule(javaTimeModule);

该逻辑被写入只有一次,它可以为多个POJO被重用



文章来源: Java 8 LocalDate Jackson format