我一直在寻找能够解决这个问题的事情,但到目前为止我还没有好运。
我的问题很简单:如何使用Jackson正确反序列化匿名对象。
private interface Interface1
{
int getValue();
}
public static void testAnonymousObject() throws IOException
{
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
mapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE);
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
Interface1 testObject = new Interface1()
{
private final int value = 5;
@Override
public int getValue()
{
return value;
}
};
String json = mapper.writeValueAsString(testObject);
System.out.println("JSON = " + json);
Interface1 received = (Interface1) mapper.readValue(json, Object.class);
System.out.println(received);
}
在我得到异常之前,输出是:JSON = [" com.foo.test.JacksonTest $ 1",{" value":5}]:
线程中的异常" main" com.fasterxml.jackson.databind.JsonMappingException:无法将类com.foo.test.JacksonTest $ 1(类型为local / anonymous)反序列化为Bean 。
编辑为了澄清,Jackson和XStream都能够序列化该对象。但只有XStream似乎能够反序列化该对象。因此,这种情况可以起作用。
答案 0 :(得分:7)
截至我写这篇文章的时候,杰克逊似乎没有正确地序列化内部类或匿名类。然而,其他包如XStream和Kryo也会这样做。
答案 1 :(得分:0)
问题不仅仅在于它是一个内部类(可能存在问题,也可能不存在问题,取决于实现是静态的还是非静态的),而且还包括没有包含类型信息 - 杰克逊看到的只是类型Interface1
。要启用它,必须包含类型信息(“多态类型处理”),或者指定抽象类型和实现类之间的映射。
鉴于您使用的是匿名内部类,您可以通过启用所谓的“默认输入”来支持此用法(请参阅ObjectMapper
javadocs for enableDefaultTyping()
等)。
但是,如果您不想为所有非最终类型启用类型包含,您可能还需要实现特定策略。
要查看是否包含了类型ID,您可以使用默认选项之一启用默认输入,并查看正在生成的JSON:应该有一个额外的类型ID(当类名用作id时为“@class”属性)
答案 2 :(得分:0)
由于内部类没有默认的零参数构造函数(它们具有对外部/父类的隐藏引用),因此Jackson无法实例化它们。
您可以检查此link
答案 3 :(得分:0)
Jackson使用嵌套类对Java POJO进行通用JSON反序列化的现成代码片段:
static class MyJSON {
private Map<String, Object> content = new HashMap<>();
@JsonAnySetter
public void setContent(String key, Object value) {
content.put(key, value);
}
}
String json = "{\"City\":\"Prague\"}";
try {
MyPOJO myPOJO = objectMapper.readValue(json, MyPOJO.class);
String jsonAttVal = myPOJO.content.get("City").toString();
System.out.println(jsonAttVal);
} catch (IOException e) {
e.printStackTrace();
}
@JsonAnySetter
确保通用的JSON解析和填充。