rrond
rrond

Reputation: 33

How to parse complex nested JSON in java?

I have a complex nested Json

It has a body similar to this:

{
staus: "Success",
id: 1,
data: [{'Movie':'kung fu panda','% viewed': 50.5},{'Movie':'kung fu panda 2','% viewed':1.5}],
metadata: {'filters':['Movie', 'Percentage Viewed'], 'params':{'content':'Comedy', 'type': 'Movie'}}
}

The only field I care about is data, and metadata is usually an even more complex/nested field. I was trying to map this to:

@JsonIgnoreProperties(ignoreUnknown = true)
class ResponseData{
    public Data[] data;
    @JsonIgnoreProperties(ignoreUnknown = true)
    class Data{
        public String Movie;
        public double viewed;
    }
}

I was looking at Jackson as an option and writing my own serializer and use JsonIgnore to discard the metadata but can't get around it.

Any suggestion on how this could be done?

Upvotes: 3

Views: 1471

Answers (1)

Oleg Cherednik
Oleg Cherednik

Reputation: 18245

You can use jackson-utils

public class Foo {
    public static void main(String... args) {
        ResponseData responseData1 = new ResponseData(
                1,
                "Success",
                new ResponseData.Data[] {
                        new ResponseData.Data("kung fu panda", 50.5),
                        new ResponseData.Data("kung fu panda 2", 1.5) },
                new ResponseData.Metadata(
                        new HashSet<>(Arrays.asList("Movie", "Percentage Viewed")),
                        new ResponseData.Metadata.Params("Comedy", "Movie"))
        );

        String json = JacksonUtils.prettyPrint().writeValue(responseData1);
        System.out.println(json);

        ResponseData responseData2 = JacksonUtils.readValue(json, ResponseData.class);
    }
}

class ResponseData {

    private int id;
    private String status;
    private Data[] data;
    private Metadata metadata;

    public ResponseData() {
    }

    public ResponseData(int id, String status, Data[] data, Metadata metadata) {
        this.id = id;
        this.status = status;
        this.data = data;
        this.metadata = metadata;
    }

    public static class Data {
        @JsonProperty("Movie")
        private String movie;
        @JsonProperty("% viewed")
        private double viewedPercents;

        public Data() {
        }

        public Data(String movie, double viewedPercents) {
            this.movie = movie;
            this.viewedPercents = viewedPercents;
        }

    }

    public static class Metadata {
        private Set<String> filters;
        private Params params;

        public Metadata() {
        }

        public Metadata(Set<String> filters, Params params) {
            this.filters = filters;
            this.params = params;
        }

        public static class Params {
            private String content;
            private String type;

            public Params() {
            }

            public Params(String content, String type) {
                this.content = content;
                this.type = type;
            }
        }
    }
}

Console output:

{
  "id" : 1,
  "status" : "Success",
  "data" : [ {
    "Movie" : "kung fu panda",
    "% viewed" : 50.5
  }, {
    "Movie" : "kung fu panda 2",
    "% viewed" : 1.5
  } ],
  "metadata" : {
    "filters" : [ "Movie", "Percentage Viewed" ],
    "params" : {
      "content" : "Comedy",
      "type" : "Movie"
    }
  }
}

P.S. As an alternative, there is another util gson-utils with the same syntax.

Upvotes: 1

Related Questions