【问题标题】:How to map dynamic JSON in JAX-RS如何在 JAX-RS 中映射动态 JSON
【发布时间】:2018-05-05 20:36:23
【问题描述】:

我必须使用 JAX-RS(Resteasy 作为实现)将 JSON 映射到 Java PoJos。问题是,JSON 是动态的。看这个例子:

{
  "typeCode": "SAMPLE",
  "data": [
    {
      "id": "COMMENTS",
      "answerValue": {
        "type": "YesNoAnswer",
        "value": true
      }
    },
    {
      "id": "CHOICE",
      "answerValue": {
        "type": "SelectListAnswer",
        "values": ["choice1", "choice2"]
      }
    }
  ]
}

动态元素在数据数组中。原则上,每个条目都有一个 ID 和一个 answerValue。但 answerValue 是动态的。根据他的类型,他可以有单个值(布尔值、字符串、对象编号)或值数组。

如何将其映射到我的 Java 模型?

【问题讨论】:

  • 取决于您想要的 Java 表示形式。 type 字段会是 String 吗?看起来enum 也很合适。 id 也一样。 Java 类需要做什么?

标签: java json jackson jax-rs resteasy


【解决方案1】:

我建议您通过将answerValue 节点作为JsonNode 类型来处理它,并手动将其处理为您需要的Java 类型。

大致如下:

class Data {
    public String typeCode;
    public List<Answer> data;
}

class Answer {
    public String id;

    public void setAnswerValue(JsonNode node) {
        String type = node.path("type").asText();

        switch (type) {
            case "YesNoAnswer" :
                boolean value = node.path("value").asBoolean();
                // TODO Handle
                break;
            case "SelectListAnswer" :
                JsonNode values = node.path("values");
                for (JsonNode v : values) {
                    String s = v.textValue();
                    // TODO Handle
                }

                break;
          }
    }
}

然后可以使用ObjectMapper 读取您的输入:

ObjectMapper om = new ObjectMapper();
Data data = om.readValue(input, Data.class);

【讨论】:

  • 嗨@Henrik 谢谢你的想法。我会试试的
  • 您好,这个建议应该可行。在尝试时,我发现了另一种解决方案(见下文)。
  • @MikeBrunner:看起来你想出了一个非常好的解决方案,实际上。我需要阅读它。看起来像一些有用的注释。
【解决方案2】:

感谢@Henrik 提供的解决方案。在实施他的建议时,我找到了一个不同的解决方案,它更适合我。 我只是使用 JsonSubTypes Annotation 来处理继承。 这是我的例子:

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.PROPERTY,
        property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = YesNoAnswer.class, name = "YesNoAnswer"),
        @JsonSubTypes.Type(value = SelectListAnswer.class, name="SelectListAnswer"),
        @JsonSubTypes.Type(value = SelectAddressAnswer.class, name="SelectAddressAnswer")})
abstract class RequestFormAnswer {

    private String type;

}

【讨论】:

    猜你喜欢
    • 2012-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-22
    • 2011-03-18
    • 1970-01-01
    • 2021-06-17
    相关资源
    最近更新 更多