简体   繁体   中英

How to map dynamic JSON in JAX-RS

I have to map a JSON to Java PoJos using JAX-RS (Resteasy as implementation). The problem is, that the JSON is dynamic. Look at this example:

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

The dynamic elements are in the data array. In principal every entry has an ID and an answerValue. But the answerValue is dynamic. Depending on his type he can have a single value (boolean, string, number an object) or an array of values.

How can I map this to my Java model?

I suggest you handle it by getting the answerValue node as a JsonNode type, and processing it manually to the Java type you need.

Something along the lines of the following:

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;
          }
    }
}

Your input can then be read with an ObjectMapper :

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

Thanks to the @Henrik of his solution. While implementing his proposal, I found a different solution, which suites better for me. I just use JsonSubTypes Annotation to handle inheritance. This is my example:

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;

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM