首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用继承将嵌套/递归JSON反序列化为Java对象

使用继承将嵌套/递归JSON反序列化为Java对象
EN

Stack Overflow用户
提问于 2018-09-25 17:07:32
回答 1查看 796关注 0票数 0

我有一个复杂的/嵌套的json。我的json文件由两个等价的java对象组成。一个是Complex_Expression,另一个是Simple_ExpressionComplex_Expression的格式如下:

{
    "SomeOpearator":0,
    "ASpecificKey":1, //the value 1 is fixed for complex expression.
    "Expressions":[ ] //array of one or more expressions
}

Simple Expression的格式如下:

{
    "Operand":"Some String Value",
    "ASpecificKey":0, //the value 0 is fixed for simple expressions.
    "SomeComparisionOpearator":1, // enums which associates int to different comparison operators.
    "Value":["String1"] //this is an array of strings.
}

Expressions又可以具有Complex_Expression和/或Simple_Expression。json文件总是从Complex_Expression开始。我必须反序列化这个JSON文件。我的最终目标是使用Complex_ExpressionSimple_Expression对象以及这些类中的一些逻辑来创建表达式。我不介意使用jacksongson,或者其他依赖项。

到目前为止,我已经创建了一个名为Expression的基类。Complex_ExpressionSimple_Expression都继承了这个类。然后我开始写Custom Json Deserializer。但在自定义的反序列化程序中,我被卡住了,我不知道该如何继续。请在这方面帮帮我。我的Simple_Expression类与Complex_Expression类类似。

public class Simple_Expression extends Expression
{
    @JsonProperty("Operand") //use jackson deserializer for this class.
    public String Operand;

    @JsonProperty("SomeComparisionOpearator")
    public SomeComparisionOpearator someCompareOperator;

    @JsonProperty("Value")
    public Object value;

    public Simple_Expression()
    {
        super(ASpecificKey.Simple); //Simple corresponds to 0
    }
}

更新

关于我的输入和输出的更多描述。输入的JSON字符串如下所示:

{
  "SomeOpearator": 0,
  "ASpecificKey": 1,
  "Expressions": [
    {
      "SomeOpearator": 1,
      "ASpecificKey": 1,
      "Expressions": [
        {
          "Operand": "People",
          "ASpecificKey": 0,
          "SomeComparisionOpearator": 14,
          "Value": [
            "Rich"
          ]
        }
      ]
    },
    {
      "SomeOpearator": 1,
      "ASpecificKey": 1,
      "Expressions": [
        {
          "Operand": "Grade",
          "ASpecificKey": 0,
          "SomeComparisionOpearator": 2,
          "Value": [
            "Grade A"
          ]
        }
      ]
    }
  ]
}

假设jackson反序列化程序,我应该能够做这样的事情:

ObjectMapper mapper = new ObjectMapper();
Expression myExpressionObject = mapper.convertValue(jsonString, Expression.class);

它应该会给我反序列化的对象到myExpressionObject中,它将由一个表达式列表(数组列表或数组,没有问题)组成。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-09-26 01:46:40

使用Gson extras RuntimeTypeAdapterFactory可以很容易做到这一点,因为您有可以用作类型鉴别器的字段ASpecificKey。有关用法,请参阅this。如果你已经包含了Gson,你可以直接将源代码复制到你的项目中。

我擅自修改了您的Java命名约定,这样类看起来就像(而且您的JSON也应该修正为正确的约定):

@Getter @Setter
public class Expression {
    private int aSpecificKey;
}

@Getter @Setter
public class SimpleExpression extends Expression {
    public SimpleExpression() {
        setASpecificKey(0);
    }
    private String operand;
    private int someComparisonOperator;
    private String[] values; 
}

@Getter @Setter
public class ComplexExpression extends Expression {
    public ComplexExpression() {
        setASpecificKey(1);
    }   
    private String someOperator;
    private Expression[] expressions;
}

对于这种RuntimeTypeAdapterFactory,您可以只实例化一个特定的DTO

final RuntimeTypeAdapterFactory<Expression> expressionTypeFactory = 
    RuntimeTypeAdapterFactory               
        .of(Expression.class, "aSpecificKey")
        .registerSubtype(SimpleExpression.class, "0")
        .registerSubtype(ComplexExpression.class, "1")

然后反序列化将如下所示:

Expression e = getGson(expressionTypeFactory)
        .fromJson(getPackageResourceReader(YOUR_NOTATION_FIXED_JSON),
                                               Expression.class);

注意,默认情况下,Gson不会反序列化类型鉴别器aSpecificKey,这就是为什么有默认构造函数来设置它的原因。如果你不需要它,你可以删除默认的构造函数。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52494443

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档