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

deserialize Json to Java with Polymorphic members

我正在尝试使用 genson 将 json 字符串反序列化为 java 对象,但未能成功。我的 class 结构是这样的:

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。

我想到了这个解决方案。如果谁能给出更好的解决方案,我很乐意采纳

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
}

您可以为您的 class 注册一些别名,然后在您的 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 以使用私有字段。

最后请注意,class 元数据属性必须在没有 @ 前缀的属性之前定义。如果您使用 Genson 生成此 json,它将始终遵守此约束。