-1

I have what I believe is called nested JSON and I want to use Jackson to deserialize into objects. Is it possible to automatically parse the child objects into Java Objects as well if a Program class had for example objects of the type TrackedEntity and ProgramStage (see JSON code) ? Alternatively would it be possible to simply parse the "id" of the respective objects and put them in Strings in the Program objects?

JSON Example is as follows:

{
programs: 
[
{
    "id": "IpHINAT79UW",
    "created": "2013-03-04T10:41:07.494+0000",
    "trackedEntity": 
    {
        "id": "cyl5vuJ5ETQ",
        "name": "Person"
    },
    "programStages":
    [
        {
            "id": "A03MvHHogjR",
        },
        {
            "id": "ZzYYXq4EJie",
        },
        {
            "id": "AREMvHHogjR",
        },
        {
            "id": "ZzYYXq4fJie",
        }
    ]
},
{
    "id": "IGRINAT79UW",
    "created": "2013-03-04T10:41:07.494+0000",
    "trackedEntity": 
    {
        "id": "cyl5vuJ5ETQ",
        "name": "Person"
    },
    "programStages":
    [
        {
            "id": "A03MvHHogjR",
        },
        {
            "id": "ZzYYXq4fJie",
        },
        {
            "id": "A01MvHHogjR",
        },
        {
            "id": "ZzGYXq4fJie",
        }
    ]
}
]
}
Simen Russnes
  • 2,002
  • 2
  • 26
  • 56

3 Answers3

1

Yes. You should be fine. Crate a data structure which represents your data:

public class Container
{
    public List<ProgramInfo> programs {get;set;}
}

public class ProgramInfo
{
   public string id{get; set;}
   public DateTime created{get;set;}
   public TrackEntity trrack{get;set;}
}

public class TrackEntity
{
    public string id{get;set;}
    public string name{get;set;}
}


//Then call the deserialise or serialize
Container container = new JavaScriptSerializer().Deserialize<Container>(yourString);
Noel
  • 567
  • 1
  • 4
  • 11
1

One approach is simply to create POJOs for the various entities.

If you assume the following for TrackEntity

class TrackedEntity {
    private final String id;
    private final String name;

    @JsonCreator
    TrackedEntity(
            @JsonProperty("id") final String id,
            @JsonProperty("name") final String name) {
        this.id = id;
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }
}

Then the following may be suitable for ProgramStage:

class ProgramStage {
    private final String id;

    @JsonCreator
    ProgramStage(@JsonProperty("id") final String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }
}

The Program class is slightly trickier since it must parse som kind of zoned date. I have used the Java 8 ZonedDateTime in this example with a custom formatter. You can also use JSR 310 module as described in this answer.

class Program {
    private static final DateTimeFormatter FORMATTER = 
            DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSxx");
    private final ZonedDateTime created;
    private final String id;
    private final List<ProgramStage> programStages;
    private final TrackedEntity trackedEntity;

    @JsonCreator
    public static Program of(
            @JsonProperty("id") final String id,
            @JsonProperty("created") final String created,
            @JsonProperty("trackedEntity") final TrackedEntity trackedEntity,
            @JsonProperty("programStages") final List<ProgramStage> programStages) {

        return new Program(
                id, 
                ZonedDateTime.parse(created, FORMATTER), 
                trackedEntity, 
                programStages);
    }

    public Program(
            final String id,
            final ZonedDateTime created,
            final TrackedEntity trackedEntity,
            final List<ProgramStage> programStages) {
        this.id = id;
        this.created = created;
        this.trackedEntity = trackedEntity;
        this.programStages = programStages;
    }

    public ZonedDateTime getCreated() {
        return created;
    }

    public String getId() {
        return id;
    }

    public List<ProgramStage> getProgramStages() {
        return programStages;
    }

    public TrackedEntity getTrackedEntity() {
        return trackedEntity;
    }
}

Finally, to fix the outer programs entity the following can be used:

class Programs {
    private final List<Program> programs;

    @JsonCreator
    Programs(@JsonProperty("programs") final List<Program> programs) {
        this.programs = programs;
    }

    public List<Program> getPrograms() {
        return programs;
    }
}

To use the whole thing, simply instantiate an ObjectMapper and use the readValue method like this:

final Programs programs = new ObjectMapper().readValue(json, Programs.class);
Community
  • 1
  • 1
wassgren
  • 18,651
  • 6
  • 63
  • 77
  • To fix the outer programs entity you could also just use a JsonNode to get the "programs": `JsonNode node = objectMapper.readTree( response.getRawContents() ); node = node.get("programs"); TypeReference> typeRef = new TypeReference>(){}; List programs = objectMapper. readValue( node.traverse(), typeRef);` – Simen Russnes Feb 18 '15 at 08:45
  • One part of my question has gone unanswered though, maybe it was unclear; what if I want to simply have a String member instead of the whole TrackedEntity object in Program. Is it possible to parse the id of the TrackedEntity inner JSON Object and put it in the member String of Program (lets call it trackedEntityId) ? – Simen Russnes Feb 18 '15 at 08:52
  • @simernes, this is possible by using a custom [JsonSerializer](http://fasterxml.github.io/jackson-databind/javadoc/2.0.2/com/fasterxml/jackson/databind/JsonSerializer.html) or [JsonDeserializer](http://fasterxml.github.io/jackson-databind/javadoc/2.0.2/com/fasterxml/jackson/databind/JsonDeserializer.html) – wassgren Feb 18 '15 at 11:57
0
public class TrackedEntity
{
    public string id { get; set; }
    public string name { get; set; }
}

public class ProgramStage
{
    public string id { get; set; }
}

public class Program
{
    public string id { get; set; }
    public string created { get; set; }
    public TrackedEntity trackedEntity { get; set; }
    public List<ProgramStage> programStages { get; set; }
}

public class RootObject
{
    public List<Program> programs { get; set; }
}

//Then call the deserialise or serialize
var container = new JavaScriptSerializer().Deserialize<RootObject>(inputjson);

hope it works for you.

Janty
  • 1,708
  • 2
  • 15
  • 29
  • If you are going to copy and paste an answer with a slight amendment, please do as a comment, not a new answer. – Noel Feb 13 '15 at 15:18