【发布时间】:2014-09-03 18:28:36
【问题描述】:
我正在使用jackson-datatype-guava 和Jackson 来处理Guava 对象的序列化。这一切都适用于其他对象,但面临Optional 的问题。
我有一个来自框架的序列化器反序列化器接口,我不得不使用以下方法。
String toJson(Object object);
<T> T fromJson(String json, Class<T> valueType);
这意味着我使用ObjectMapper的这个接口的Jackson实现也只能在mapper上使用以下方法。
mapper.readValue(json, valueType);
这在“可选”的情况下不起作用。
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new GuavaModule());
mapper.readValue(mapper.writeValueAsString(Optional.of("string")), Optional.class);
这会给出错误提示 Null JavaType passed。如果我在映射器中使用TypeReferece<Optional<String>>,它可以正常工作,但有没有办法让它与上述界面一起工作?
//works fine but can't use this method as interface only accepts `Class` param.
mapper.readValue(mapper.writeValueAsString(Optional.of("string")), new TypeReference<Optional<String>>(){});
更新
我尝试按照 cmets 中的建议使用这些库的 2.4.* 版本,它对 Optional<String> 工作正常,但对 Optional<MyClass> 仍然不起作用,其中 MyClass 是简单的 pojo。似乎在反序列化时,它认为MyClass 的json 是一个映射并将其转换为Optional<Map>。
public class MyClass {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
主程序:
MyClass obj = new MyClass();
obj.setName("PAC");
Optional<MyClass> obj1 = mapper.readValue(mapper.writeValueAsString(Optional.of(obj)), Optional.class);
System.out.println(obj1); //prints as Map
System.out.println(obj1.get().getName()); //Fails doing casting to MyClass
输出:
Exception in thread "main" Optional.of({name=PAC})
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to MyClass
at OptionalTest.main(OptionalTest.java:22)
我还尝试通过mapper.enableDefaultTyping() 在映射器中启用默认输入,但没有任何运气。
为DefaultTyping.NON_FINAL 启用默认类型后,mapper.readValue... 行出错
Invalid type id 'MyClass' (for id type 'Id.class'): Class MyClass is not assignable to com.google.common.base.Optional
对此有什么进一步的建议吗?
【问题讨论】:
-
你能澄清什么失败了吗?与
Optional.class通话对我有用。 -
以及哪个版本的 Java。
-
@SotiriosDelimanolis 这很奇怪。我正在使用带有 Java 7 的
Jackson-databind和Jackson-datatype-guava的 2.3.2 版本。 -
jackson 使用 2.4.1,guava 的数据类型使用 2.4.2。
-
@SotiriosDelimanolis,确实它适用于 2.4.* 版本。不知道为什么会这样。我以
Optional<String>为例,它正在工作,但它还不能再次用于普通的 pojo 类。