2014-11-03 74 views
0

我有以下用例:吨我的ObjRef子类是这种形式(代码简化的)的:杰克逊2.4.3冲突的创作者

public class PlatformRef extends ObjRef { 
    public PlatformRef() {} 
    public PlatformRef(long id) {} 
    public PlatformRef(Long id) {); 
} 

反序列化。当(I有这些类中的对象的阵列要反序列化,我的映射器使用默认打字)

... 
    "platforms" : [ { 
     "id" : 20001, 
     "name" : "my_platformRef_name", 
     "idAsLong" : 20001 
     }, { 
     "id" : 30001, 
     "name" : null, 
     "idAsLong" : 30001 
     } ] 
    ... 

杰克逊2.4.3抛出:com.fasterxml.jackson.databind.JsonMappingException:冲突的长期创

我已经特里d使用ValueInstantiators#findValueInstantiator指向这些ObjRef子类的自定义实例化器。

它失败了,因为BasicDeserializerFactory#findValueInstantiator首先找到bean的所有可能的ctors(它如上所述失败),然后试图找到用户定义的那些。

我如何排序了这一点,因为:

  1. 我不能改变的类,所以我不能使用注释
  2. 有这些类的一个大数目,使用JsonIgnore/JSonCreator混入会工作但丑

回答

0

使用自定义排序AnnotationIntrospector它:

mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() { 
    @Override 
    public Object findValueInstantiator(AnnotatedClass ac) { 
     if (ObjRef.class.isAssignableFrom(ac.getAnnotated())) { 
      return new StdCtorValueInstantiator(ac); 
     } 
     return super.findValueInstantiator(ac); 
    } 
}); 

private static class StdCtorValueInstantiator extends ValueInstantiator { 

    private AnnotatedClass annotated; 

    public StdCtorValueInstantiator(AnnotatedClass ac) { 
     annotated = ac; 
    } 

    @Override 
    public String getValueTypeDesc() { 
     return "Subclass_of_ObjRef"; 
    } 

    @Override 
    public boolean canCreateUsingDefault() { 
     return true; 
    } 

    @Override 
    public Object createUsingDefault(DeserializationContext ctxt) throws IOException { 
     try { 
      return annotated.getDefaultConstructor().getAnnotated().newInstance(); 
     } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { 
      throw new IOException("Could not create an instance of " + annotated.getAnnotated() 
        + " using the default c-tor"); 
     } 
    } 

}