2015-02-09 32 views
4

我一直在寻找答案的东西,但我迄今没有很多运气。杰克逊反序列化与匿名类

我的问题很简单:如何正确使用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”,{ “值”:5}]之前我得到一个异常:在螺纹

异常“主“com.fasterxml.jackson.databind.JsonMappingException:无法将类com.foo.test.JacksonTest $ 1(类型为local/anonymous)反序列化为Bean

编辑为了澄清,Jackson和XStream都能够序列化对象。但是只有XStream似乎能够将对象反序列化。所以这个场景可以工作。

+1

内部类实例需要构造其外部类的实例。杰克逊会用什么?它将如何创建外部类实例?顶级类和静态嵌套类有什么问题? – 2015-02-09 20:23:09

+0

这里被序列化/反序列化的对象只是一个空接口的匿名实现。 问题是我正在转换已经使用XStream序列化的大型代码库来使用Jackson。匿名对象在代码中相当常见。在这种情况下,XStream能够序列化和反序列化这个对象。杰克逊只能序列化,但不能反序列化。 – sydraz 2015-02-09 20:26:53

回答

6

截至我写这篇文章时,Jackson似乎没有正确地序列化内部类或匿名类。但是,其他软件包,如XStream和Kryo​​,则可以。

+4

你的意思是杰克逊没有_deserialize_非静态内部类。支持静态内部类。 – StaxMan 2015-02-12 07:07:26

+1

是的,我很抱歉不清楚 – sydraz 2015-02-27 18:59:52

0

问题不只是它是一个内部类(其可以是或可以不是问题,取决于实现是静态的还是非静态),而且在没有任何类型的信息被包括 - 所有杰克逊看到的是键入Interface1。为了使其能够读回,必须包含类型信息(“多态类型处理”),或者指定抽象类型和实现类之间的映射。

鉴于您使用的是匿名内部类,您可以通过启用所谓的“默认类型”来支持此用法(请参阅ObjectMapper javadocs for enableDefaultTyping()等)。 但是如果您不想为所有非最终类型启用类型包含,您可能还需要实现特定策略。

要查看是否包含类型id,可以使用默认选项之一启用默认类型,并查看正在生成的JSON:应该有一个额外的类型id(类名称为“@class”属性时用作id )。

+0

我实际上启用了默认的输入,这就是为什么JSON,也包括在问题中,包含类名称“com.foo.test.JacksonTest $ 1。但我不知道如何让序列化的JSON反序列化正确(注意它有正确的类名) – sydraz 2015-02-09 22:56:17

+0

啊,然后问题是匿名内部类不是静态的,并且需要所谓的“implicit”这个指针,这是不受支持的 – StaxMan 2015-02-12 07:06:15