我无法理解为什么在尝试序列化对象时,我得到一个与反序列化相关的异常。我的对象有一个joda类型为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值转换为对象?我尝试添加自定义反序列化器,但它不起作用。
更新更多例外:
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);
.....
}
解串器本身。我实际上没有转换,只是概念证明:
private static class CustomLocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
@Override
public LocalDateTime deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
return new LocalDateTime();
}
}
答案 0 :(得分:1)
我发现了问题(或者我的同事实际上是这样做的)。这是我见过的最愚蠢的java行为。问题是,包含 LocalDateTime 字段的DTO是通过 reflection 填充的,似乎可以成功设置类型String
的值。当您尝试使用此字段时(而不是在设置时),会发生类强制转换异常。
public class MyDto {
// trough reflection, the contained object is a java.lang.String
private LocalDateTime myDate;
}
如果你问为什么会这样 - 因为我们没有为LocalDateTime
配置转换器,而是为DateTime
配置了转换器。我的同事错误地使用了LocalDateTime
,杰克逊默默地将其反序列为String
答案 1 :(得分:0)
我写了一个快速测试课来检查你提供的内容。它似乎运行良好并输出以下内容:
{"value":[2014,2,24,13,42,44,745]}
当然,这可能不是您正在寻找的确切格式,但不管怎样,这是类:
public class JsonSerialization {
public static void main(final String[] args) {
try {
final Response response = new Response();
final ObjectMapper mapper = new ObjectMapper();
final String value = mapper.writeValueAsString(response);
System.out.println(value);
}
catch (final Exception e) {
e.printStackTrace();
}
}
public static class Response {
LocalDateTime value = new LocalDateTime();
public LocalDateTime getValue() {
return this.value;
}
public void setValue(final LocalDateTime value) {
this.value = value;
}
}
}
我想这引出了一些问题:
registrationDate
)是否有getter和setter?writeValueAsString
方法?我知道这不是你问题的一部分,但是在Jackson的1.9.13中,你应该注册这样的自定义(de)序列化器:
SimpleModule module = new SimpleModule("", new Version(1, 0, 0, "");
module.addDeserializer(LocalDateTime.class, new CustomLocalDateTimeDeserializer());
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);
答案 2 :(得分:0)
使用JodaModule模块注册您的映射器。
mapper.register(new JodaModule())
或尝试使用JodaMapper:
import com.fasterxml.jackson.datatype.joda.JodaMapper;
public static void main(String args[]){
DateTime dateTime = new DateTime(12353434);
JodaMapper mapper = new JodaMapper();
try {
serializedString = mapper.writeValueAsString(dateTime);
System.out.println(serializedString);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
控制台输出:
12353434