使用多态成员将 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
可能有另一个 ComplexCondition
或 SimpleCondition
作为 left
和 right
的成员。我得到的json是这样的:
{
"left": {
"feature":"locality",
"op":"==",
"value":"Chino"
"primitive":9,
},
"joint":"and",
"right": {
"feature":"ch4",
"op":">=",
"value":"1.5",
"primitive":3
}
}
在这个 json 中,一个 ComplexCondition
同时具有 left
和 right
作为 SimpleCondition
。但是我收到的一般 json 字符串可以是从 SimpleCondition
到 ComplexCondition
的任何嵌套级别的任何内容。我尝试在 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,它将始终遵守此约束。
我正在尝试使用 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
可能有另一个 ComplexCondition
或 SimpleCondition
作为 left
和 right
的成员。我得到的json是这样的:
{
"left": {
"feature":"locality",
"op":"==",
"value":"Chino"
"primitive":9,
},
"joint":"and",
"right": {
"feature":"ch4",
"op":">=",
"value":"1.5",
"primitive":3
}
}
在这个 json 中,一个 ComplexCondition
同时具有 left
和 right
作为 SimpleCondition
。但是我收到的一般 json 字符串可以是从 SimpleCondition
到 ComplexCondition
的任何嵌套级别的任何内容。我尝试在 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,它将始终遵守此约束。