Spring 启动无法反序列化包含 OffsetDateTime 的对象
Spring Boot Cannot Deserialize Object That contanis OffsetDateTime
我正在尝试调用一个休息端点,它 return 是一个看起来像这样的 pojo 对象:
public class Process {
@JsonProperty("id")
private String id = null;
@JsonProperty("processDefinitionId")
private String processDefinitionId = null;
@JsonProperty("businessKey")
private String businessKey = null;
@JsonProperty("startedAt")
private OffsetDateTime startedAt = null;
@JsonProperty("endedAt")
private OffsetDateTime endedAt = null;
@JsonProperty("durationInMs")
private Integer durationInMs = null;
@JsonProperty("startActivityDefinitionId")
private String startActivityDefinitionId = null;
@JsonProperty("endActivityDefinitionId")
private String endActivityDefinitionId = null;
@JsonProperty("startUserId")
private String startUserId = null;
@JsonProperty("deleteReason")
private String deleteReason = null;
//constructors and setters+getters
}
调用如下:
ResponseEntity<Process> responseModel = restTemplate.exchange("http://localhost:8062/processes", HttpMethod.POST, httpEntity, Process.class);
问题是我尝试了一些方法,例如忽略 OffsetDateTime 属性或尝试更改该日期的格式,但它会抛出此错误:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `org.threeten.bp.OffsetDateTime` (no Creators, like default construct, exist): no String-argument constructor/factory method to deserialize from String value ('2019-10-04T13:20:29.315Z')
否则它会 return null :(
解决这个问题的好方法是什么?
错误指出它无法构造 org.threeten.bp.OffsetDateTime 的实例。你需要使用
java.time.offsetdatetime
然后在您的模型中,您可以按照自己喜欢的方式对其进行格式化,例如
@JsonProperty("endedAt") //this line is not needed when it is the same as the instance variable name
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd@HH:mm:ss.SSSZ")
private OffsetDateTime endedAt;
我对 swagger 生成的 bean 也有同样的问题。为了解决这个问题,我为日期类型创建了一些序列化器和反序列化器:org.threeten.bp.LocalDate 和 org.threeten.bp.OffsetDateTime。而且效果很好 :).
@Bean
@Primary
public ObjectMapper serializingObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(OffsetDateTime.class, new OffsetDateTimeSerializer());
javaTimeModule.addDeserializer(OffsetDateTime.class, new OffsetDateTimeDeserializer());
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer());
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer());
objectMapper.registerModule(javaTimeModule);
return objectMapper;
}
public static class OffsetDateTimeSerializer extends JsonSerializer<OffsetDateTime> {
@Override
public void serialize(OffsetDateTime arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
arg1.writeString(arg0.toString());
}
}
public static class OffsetDateTimeDeserializer extends JsonDeserializer<OffsetDateTime> {
@Override
public OffsetDateTime deserialize(JsonParser arg0, DeserializationContext arg1) throws IOException {
return OffsetDateTime.parse(arg0.getText());
}
}
public static class LocalDateSerializer extends JsonSerializer<LocalDate> {
@Override
public void serialize(LocalDate arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
arg1.writeString(arg0.toString());
}
}
public static class LocalDateDeserializer extends JsonDeserializer<LocalDate> {
@Override
public LocalDate deserialize(JsonParser arg0, DeserializationContext arg1) throws IOException {
return LocalDate.parse(arg0.getText());
}
}
我正在尝试调用一个休息端点,它 return 是一个看起来像这样的 pojo 对象:
public class Process {
@JsonProperty("id")
private String id = null;
@JsonProperty("processDefinitionId")
private String processDefinitionId = null;
@JsonProperty("businessKey")
private String businessKey = null;
@JsonProperty("startedAt")
private OffsetDateTime startedAt = null;
@JsonProperty("endedAt")
private OffsetDateTime endedAt = null;
@JsonProperty("durationInMs")
private Integer durationInMs = null;
@JsonProperty("startActivityDefinitionId")
private String startActivityDefinitionId = null;
@JsonProperty("endActivityDefinitionId")
private String endActivityDefinitionId = null;
@JsonProperty("startUserId")
private String startUserId = null;
@JsonProperty("deleteReason")
private String deleteReason = null;
//constructors and setters+getters
}
调用如下:
ResponseEntity<Process> responseModel = restTemplate.exchange("http://localhost:8062/processes", HttpMethod.POST, httpEntity, Process.class);
问题是我尝试了一些方法,例如忽略 OffsetDateTime 属性或尝试更改该日期的格式,但它会抛出此错误:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `org.threeten.bp.OffsetDateTime` (no Creators, like default construct, exist): no String-argument constructor/factory method to deserialize from String value ('2019-10-04T13:20:29.315Z')
否则它会 return null :( 解决这个问题的好方法是什么?
错误指出它无法构造 org.threeten.bp.OffsetDateTime 的实例。你需要使用
java.time.offsetdatetime
然后在您的模型中,您可以按照自己喜欢的方式对其进行格式化,例如
@JsonProperty("endedAt") //this line is not needed when it is the same as the instance variable name
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd@HH:mm:ss.SSSZ")
private OffsetDateTime endedAt;
我对 swagger 生成的 bean 也有同样的问题。为了解决这个问题,我为日期类型创建了一些序列化器和反序列化器:org.threeten.bp.LocalDate 和 org.threeten.bp.OffsetDateTime。而且效果很好 :).
@Bean
@Primary
public ObjectMapper serializingObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(OffsetDateTime.class, new OffsetDateTimeSerializer());
javaTimeModule.addDeserializer(OffsetDateTime.class, new OffsetDateTimeDeserializer());
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer());
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer());
objectMapper.registerModule(javaTimeModule);
return objectMapper;
}
public static class OffsetDateTimeSerializer extends JsonSerializer<OffsetDateTime> {
@Override
public void serialize(OffsetDateTime arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
arg1.writeString(arg0.toString());
}
}
public static class OffsetDateTimeDeserializer extends JsonDeserializer<OffsetDateTime> {
@Override
public OffsetDateTime deserialize(JsonParser arg0, DeserializationContext arg1) throws IOException {
return OffsetDateTime.parse(arg0.getText());
}
}
public static class LocalDateSerializer extends JsonSerializer<LocalDate> {
@Override
public void serialize(LocalDate arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
arg1.writeString(arg0.toString());
}
}
public static class LocalDateDeserializer extends JsonDeserializer<LocalDate> {
@Override
public LocalDate deserialize(JsonParser arg0, DeserializationContext arg1) throws IOException {
return LocalDate.parse(arg0.getText());
}
}