对于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:
我从来没有能够得到这个工作使用注释简单。 为了得到它的工作,我创建了一个ContextResolver
为ObjectMapper
,然后我添加了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