杰克逊:如何用速记属性值对json进行反序列化

时间:2015-06-02 14:51:48

标签: java json jackson deserialization

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

RelativeLayout relativeLayout = new RelativeLayout(this);
relativeLayout.addRule(RelativeLayout.CENTER_IN_PARENT);


RelativeLayout linearLayout = new RelativeLayout(this);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(20,20);
RelativeLayout.LayoutParams numPicerParams1=new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
RelativeLayout.LayoutParams numPicerParams2=new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
numPicerParams1.addRule(RelativeLayout.LEFT_OF);
numPicerParams2.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);

linearLayout.setLayoutParams(params);
linearLayout.addView(np1, numPicerParams1);
linearLayout.addView(np2, numPicerParams2);
linearLayout.addView(t1,numPicerParams1);
linearLayout.addView(t2,numPicerParams2);

relativeLayout.addView(linearLayout);

此处的“type”属性可以是字符串或对象。如果它是一个字符串,那么它被认为是具有默认属性的同一对象的简单形式。即上例中的1和2是等效的。

据我所知,可以为整个'type'对象编写Custom Deserializer。据我所知,在这种情况下,我必须手动反序列化整个'type'对象。但我真的想手动处理简写形式并将正常处理委托给基于注释的映射器。这可能吗?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

您可能需要为BeanDeserializer编写自定义type子类。但是,您可以利用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()手动阅读种类值以转到someOtherThing,但我希望这足以让您入门。