问题描述
我不知道为什么在尝试序列化对象时会出现异常,该异常看上去与反序列化有关.我的对象的字段为joda类型LocalDateTime
I can't figure why when trying to serialize an object I get an exception which looks related to deserialization. My object has a field which is of joda type LocalDateTime
ObjectMapper mapper = new ObjectMapper();
mapper.writeValueAsString(response));
我遇到以下异常:
org.codehaus.jackson.map.JsonMappingException: java.lang.String cannot be cast to org.joda.time.LocalDateTime
我正在尝试序列化.为什么要尝试将String值转换为对象?我试图添加自定义反序列化器,但是它不起作用.
I am trying to serialize. Why it is trying to convert String value to object? I tried to add custom deserializers, but it does not work.
更新更多例外情况:
org.codehaus.jackson.map.JsonMappingException: java.lang.String cannot be cast to org.joda.time.LocalDateTime (through reference chain: com.my.AccountDetailResponse["registrationDate"])
at org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:218) ~[jackson-mapper-asl-1.9.13.jar:1.9.13]
at org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:183) ~[jackson-mapper-asl-1.9.13.jar:1.9.13]
at org.codehaus.jackson.map.ser.std.SerializerBase.wrapAndThrow(SerializerBase.java:140) ~[jackson-mapper-asl-1.9.13.jar:1.9.13]
at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:158) ~[jackson-mapper-asl-1.9.13.jar:1.9.13]
at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112) ~[jackson-mapper-asl-1.9.13.jar:1.9.13]
at org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:610) ~[jackson-mapper-asl-1.9.13.jar:1.9.13]
at org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:256) ~[jackson-mapper-asl-1.9.13.jar:1.9.13]
at org.codehaus.jackson.map.ObjectMapper._configAndWriteValue(ObjectMapper.java:2575) ~[jackson-mapper-asl-1.9.13.jar:1.9.13]
at org.codehaus.jackson.map.ObjectMapper.writeValueAsString(ObjectMapper.java:2097) ~[jackson-mapper-asl-1.9.13.jar:1.9.13]
试图添加反序列化器:
CustomDeserializerFactory deserializerFactory = new CustomDeserializerFactory();
deserializerFactory.addSpecificMapping(LocalDateTime.class, new CustomLocalDateTimeDeserializer());
ObjectMapper mapper = new ObjectMapper();
mapper.setDeserializerProvider(new StdDeserializerProvider(deserializerFactory));
try {
remoteActionDto.setPayload(mapper.writeValueAsString(response));
} catch (IOException e) {
logger.error("Can not convert response to json!", e);
.....
}
解串器本身.我实际上并没有进行转换,而只是概念证明:
the deserializer itself. I does not convert actually, but only proof of concept:
private static class CustomLocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
@Override
public LocalDateTime deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
return new LocalDateTime();
}
}
推荐答案
我发现了问题(或者实际上是我的一位同事做到了).这是我见过的最愚蠢的Java行为.问题在于,包含 LocalDateTime 字段的DTO是通过 reflection 填充的,并且似乎可以成功设置类型为 String
的值.当您尝试使用此字段时(而不是在设置该字段时),将发生类强制转换异常.
I found the problem (or actually a colleague of mine did it). It is the most stupid java behaviour I've ever met. The problem was, that the DTO which contained the LocalDateTime field was populated via reflection, and it seems possible to successfully set a value of type String
. A class cast exception occurs when you try to use this field (not when it is being set).
public class MyDto {
// trough reflection, the contained object is a java.lang.String
private LocalDateTime myDate;
}
如果您问为什么会这样-因为我们没有为 LocalDateTime
配置转换器,而是为 DateTime
配置了转换器.我的同事错误地使用了 LocalDateTime
,杰克逊默默地将其反序列化为 String
If you ask why this happened - because we haven't configured a converter for LocalDateTime
, but for DateTime
instead. My colleague used LocalDateTime
by mistake and Jackson silently deserialized it as a String
这篇关于尝试序列化LocalDateTime时的Jackson序列化异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!