简体   繁体   中英

Jackson inheritance - parsing nested JSON in a subclass using @JsonProperty

I am trying to use Jackson to parse network responses. All responses follow this general format:

{
  "status": {
    "code": 0,
    "message": "ok",
    "version": 1
  },
  "data": {
    "accountId": 1111,
    "handle": "mark",
    "stats": {
       "wins": 11,
       "losses": 43
    }
  }
}

The "status" node is shared among all objects, while the "data" node will vary from response to response. My thought was to create a NetworkResponse class that handles parsing the "status" node and then create many objects that inherit from NetworkResponse that parse the different NetworkResponses I'm getting.

So far, I made this for the base class:

public class NetworkResponse {
    @JsonProperty("status") protected StatusNode statusNode;

    public NetworkResponse() { }
}

And then a subclass that would parse the above network response:

public class PlayerInfoResponse extends NetworkResponse {
    @JsonProperty("accountId") private String accountId;
    @JsonProperty("handle") private String handle;
    @JsonProperty("stats") private PlayerStats playerStats;

    public PlayerInfoResponse() {}
}

The problem here is neither the superclass nor child class acknowledge the "data" node. Now, I could implement the child class like this:

public class PlayerInfoResponse extends NetworkResponse {
    private String accountId;
    private String handle;
    private PlayerStats playerStats;

    @JsonProperty("data") public JsonNode dataNode;
    public void setDataNode(JsonNode dataNode) {
            // parse out data manually 
    }

    public PlayerInfoResponse() {}
}

This works, but I'd like to use @JsonProperty to keep every tidier. Is there anyway to get Jackson to treat the "data" node as the node it should be using when parsing? Here's the code I'm using to do the mapping:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
PlayerInfoResponse info = objectMapper.readValue(jsonResponse, PlayerInfoResponse.class);

Thanks!

A couple of ways to go about this.

Simplest way is just restructure your response.

public abstract class NetworkResponse {
  @JsonProperty("status") private StatusNode statusNode;
  // getters and setters
}

public class PlayerInfoResponse extends NetworkResponse {
    private PlayerData data;

    public static class PlayerData {
      private String accountId;
      private String handle;
      @JsonProperty("stats") private PlayerStats playerStats;

      // getters and setters
    }
    // getters and setters
 }  

If you noticed, you a json field data not defined, in your player response object

Also, @JsonProperty just lets you rename the mapping between a java bean field and it's json counterpart.

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