繁体   English   中英

杰克逊:如何使用简写属性值反序列化json

[英]Jackson: How to deserialize json with shorthand property value

我正在努力寻找如何使用Jackson将遵循速记约定的JSON反序列化为Java POJO。

[
  { 
    "id":1,
    "type": "simple"
  },
  { 
    "id":2,
    "type": { "kind": "simple" }
  },
  { 
    "id":3,
    "type": {
      "kind": "complex",
      "someOtherThing": "value"
    }
  }
]

此处的“ type”属性可以是字符串或对象。 如果是字符串,则将其视为具有默认属性的同一对象的简单形式。 上面示例中的即1和2是等效的。

据我了解,可以为整个“类型”对象编写自定义反序列化程序。 据我了解,在这种情况下,我将不得不手动反序列化整个“类型”对象。 但我真的想只手动处理速记形式,并将正常处理委托给基于注释的映射器。 那可能吗?

您可以简单地使用参数定义构造函数,该参数将创建具有简单类型的对象。 在您的情况下,您的Type类将具有String构造函数。 不要忘记也包括一个noargs构造函数。

public static void main(String [] args) throws JsonParseException, JsonMappingException, IOException {
    String str = "[ {\"id\":1,\"type\":\"simple\" }, {\"id\":2,\"type\": {\"kind\":\"simple\" } }, {\"id\":3,\"type\": {\"kind\":\"complex\",\"someOtherThing\":\"value\" } }]";
    ObjectMapper mapper = new ObjectMapper();
    MyObject[] objs = mapper.readValue(str.getBytes(), MyObject[].class);
    for(MyObject obj : objs) {
        System.out.println(obj.id + " " + obj.type.kind + " " + obj.type.someOtherThing);
    }
}

public static class MyObject {
    public String id;
    public Type type;
}

public static class Type {
    public String kind;
    public String someOtherThing;

    public Type() {
    }

    public Type(String kind) {
        this.kind = kind;
    }
}

打印出来

1 simple null
2 simple null
3 complex value

您可能需要为type编写一个自定义BeanDeserializertype 但是,您可以利用Jackson的其余部分来处理类型对象。

最好的选择是@JsonIgnore对象中的type属性。 然后,在自定义反序列化器中,覆盖handleIgnoredProperty() 在这种方法中,请执行以下操作:

protected void handleIgnoredProperty(JsonParser jp, DeserializationContext ctxt, Object beanOrClass, String propName)
        throws IOException, JsonProcessingException {
  if ("type".equals(propName)) {
     if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
       MyObjectDeserializer myObjectDeserializer = (MyObjectDeserializer) ctxt.findRootValueDeserializer(ctxt                   .getTypeFactory().constructType(MyObject.class));
       MyObject myObject = (MyObject) myObjectDeserializer.deserialize(jp, ctxt);
       // cast beanOrClass to your object and call object.setType(myObject)
     }
     else {
        // get a StringDeserializer and call object.setType(string)
     }
  }
  else {
    super.handleIgnoredProperty(jp, ctxt, beanOrClass, propName);
  }
}

您可能需要进行更多处理,才能使用jp.nextToken()手动读取kind值来获取someOtherThing但是我希望这足以使您入门。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM