【问题标题】:Jackson 2.4.3 conflicting creators杰克逊 2.4.3 冲突的创作者
【发布时间】:2014-11-03 16:14:21
【问题描述】:

我有以下用例:我的大量 ObjRef 子类都是这种形式(代码简化):

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

反序列化时(我在要反序列化的对象中有这些类的数组,我的映射器使用默认类型)

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

jackson 2.4.3 throws: com.fasterxml.jackson.databind.JsonMappingException: Conflicting long creators

我尝试使用 ValueInstantiators#findValueInstantiator 指向这些 ObjRef 子类的自定义实例化器。

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

我该如何解决这个问题,因为:

  1. 我不能更改类,所以我不能使用注释
  2. 这些类的数量很多,使用 JsonIgnore/JSonCreator 混合可以工作,但很难看

【问题讨论】:

    标签: json jackson


    【解决方案1】:

    使用自定义的 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");
            }
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2018-12-12
      • 1970-01-01
      • 2023-04-03
      • 2015-04-19
      • 2017-03-08
      • 2011-06-26
      • 1970-01-01
      • 2013-07-06
      • 2013-12-12
      相关资源
      最近更新 更多