使用Polymorphic成员将Json反序列化为Java

时间:2016-05-24 22:04:32

标签: java json jackson json-deserialization genson

我尝试使用genson将json字符串反序列化为java对象但无法成功。我的班级结构是这样的:

public class Condition {
}

public class SimpleCondition extends Condition {
    String feature;
    String op;
    String value;
    int primitive;
}

public class ComplexCondition extends Condition {
    private Condition left;
    private String joint;
    private Condition right;
}

正如您所看到的,ComplexCondition可能有另外ComplexConditionSimpleCondition作为leftright的成员。我得到的json是这样的:

{
  "left": {
            "feature":"locality",
            "op":"==",
            "value":"Chino"
            "primitive":9,
          },
  "joint":"and",
  "right": {
              "feature":"ch4",
              "op":">=",
              "value":"1.5",
              "primitive":3
           }
}

在这个json中,ComplexCondition同时包含leftright SimpleCondition。但是我收到的一般json字符串可以是SimpleConditionComplexCondition的任何嵌套级别。我尝试在json字符串中设置@class值,但genson仍然无法反序列化它。感谢您使用任何库将此json反序列化为java的任何帮助。

2 个答案:

答案 0 :(得分:1)

您可以为您的类注册一些别名,然后在您的json中引用它们,如下所示:

Genson genson = new GensonBuilder()
    .addAlias("ComplexCondition", ComplexCondition.class)
    .addAlias("SimpleCondition", SimpleCondition.class)
    .create();

{
  "@class": "ComplexCondition",
  "left": {
            "@class": "SimpleCondition",
            "feature":"locality",
            "op":"==",
            "value":"Chino",
            "primitive":9
          },
  "joint":"and",
  "right": {
            "@class": "SimpleCondition",
              "feature":"ch4",
              "op":">=",
              "value":"1.5",
              "primitive":3
           }
}

您还需要为ComplexCondition添加get和set方法,或者将其字段设置为public,或者提供一个构造函数,将其作为参数或将genson配置为使用私有字段。

最后一点,必须在没有@前缀的属性之前定义类元数据属性。如果你用Genson生成这个json,它将始终遵守这个约束。

答案 1 :(得分:0)

我提出了这个解决方案。如果有人能提供更好的解决方案,我很乐意接受它。

import org.json.JSONObject;
public class Condition {
    public static Condition getCondition(JSONObject json){
        if(json.has("left"))
            return new ComplexCondition(json);
        else if(json.has("feature"))
            return new SimpleCondition(json);
        else
            throw new IllegalArgumentException("Invalid json for a Condition");
    }
}

public class ComplexCondition extends Condition{
    private Condition left;
    private String joint;
    private Condition right;

    public ComplexCondition(JSONObject json){
        if(json.has("left")){
            JSONObject leftJSON = json.getJSONObject("left");
            if(leftJSON.has("left"))
                this.left = new ComplexCondition(leftJSON);
            else
                this.left = new SimpleCondition(leftJSON);

            this.joint = json.getString("joint");

            JSONObject rightJSON = json.getJSONObject("right");
            if(rightJSON.has("left"))
                this.right = new ComplexCondition(rightJSON);
            else
                this.right = new SimpleCondition(rightJSON);
        } else {
            throw new IllegalArgumentException("invalid json for a complex condition");
        }
    }

    //getters and setters
}

public class SimpleCondition extends Condition{
    private String feature;
    private String op;
    private String value;
    private int primitive;

    public SimpleCondition(JSONObject json) {
        if(json.has("feature")){
            this.feature = json.getString("feature");
            this.op = json.getString("op");
            this.value = json.getString("value");
            this.primitive = json.getInt("primitive");
        } else
            throw new IllegalArgumentException("invalid json for a simple condition");

    }

    //getters and setters
}