【问题标题】:Deserialize JSON with Jackson with complex Polymorphic structure使用具有复杂多态结构的 Jackson 反序列化 JSON
【发布时间】:2017-01-25 10:54:07
【问题描述】:

我需要帮助,这里是任务的描述:
1.我有基础接口

interface IPolymorphicModel

2。我的嵌套接口很少:

interface IContentItem extends IPolymorphicModel
interface IAttachment extends IPolymorphicModel

3。我的实现很少:

public class MediaAttachment implements IAttachment

public class Article implements IContentItem {
private List<IAttachment> attachements;
}

我正在使用 jackson(我也尝试使用 Gson 使用 registerTypeAdapterFactory)来解析当前的 json 结构。我正在使用下一种方法对所有嵌套项使用单个 Deserializer 来反序列化 json:

Module module = new SimpleModule()
module.setDeserializerModifier(new BeanDeserializerModifier() {
public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config,
                                 BeanDescription beanDesc,
                                 JsonDeserializer<?> deserializer){
if (IPolymorphicModel.class.isAssignableFrom(beanDesc.getBeanClass())){
   return new PolymorphicJsonDeserializer()
}
return super.modifyDeserializer(config, beanDesc, deserializer);
})

但是解析内部项目存在问题:如您所见,内部对象可以包含具有相同 super 的对象,而当杰克逊尝试解析它们时,它对 IPolymorphicModel 和注册相同的内容一无所知BeanDeserializerModifier 是不可能的,因为它会导致堆栈溢出。

【问题讨论】:

    标签: java json jackson polymorphism deserialization


    【解决方案1】:

    我找到了解决方案。至少在这种情况下它很容易。要解决此类任务,您需要使用 jackson TypeIdResolver。这是一个例子:

    1.首先您需要注释您的基类,其中modelType您可以识别的字段,您正在使用哪个基类的子类:

    @JsonTypeInfo(use = JsonTypeInfo.Id.CUSTOM,
            include = JsonTypeInfo.As.PROPERTY,
            property = "modelType")
    @JsonTypeIdResolver(IdResolver.class)
    interface IPolymorphic
    

    2。实现你自己的IdResolver.class

    public class IdResolver implements TypeIdResolver {
    
        private JavaType baseType = null;
    
        @Override
        public void init(JavaType baseType) {
            this.baseType = baseType;
        }
    
        @Override
        public String idFromValue(Object value) {
            return idFromValueAndType(value, value.getClass());
        }
    
        @Override
        public String idFromValueAndType(Object value, Class<?> suggestedType) {
            String id = "";
            for (Map.Entry<String, Class<? extends IPolymorphic>> entry : PolymorphicTypeRegistry.Companion.getInstance().getMap().entrySet()) {
                if (entry.getValue() == suggestedType) return entry.getKey();
            }        
            return id;
        }
    
        @Override
        public String idFromBaseType() {
            return idFromValueAndType(null, baseType.getRawClass());
        }
    
        @Override
        public JavaType typeFromId(String id) {
            Class clazz = PolymorphicTypeRegistry.Companion.getInstance().get(id);
            JavaType javaType = TypeFactory.defaultInstance().constructSpecializedType(baseType, clazz);
            return javaType;
        }
    
        @Override
        public JavaType typeFromId(DatabindContext context, String id) {
            return typeFromId(id);
        }
    
        @Override
        public String getDescForKnownTypeIds() {
            return "";
        }
    
        @Override
        public JsonTypeInfo.Id getMechanism() {
            return JsonTypeInfo.Id.CUSTOM;
        }
    }
    
    1. 在前面的两个步骤中,我们配置 jackson 为 IPolymorphic 的所有嵌套类调用相同的反序列化行为,所以最后一步 - 我们需要为 IPolymorphic 注册反序列化器:

      public void configureJackson() {
          ObjectMapper objectMapper = new ObjectMapper();
          Module module = new SimpleModule();
          module.addDeserializer(IPolymorphic.class, new PolymorphicJsonDeserializer());
          objectMapper.registerModule(module);
      }
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多