mattx
mattx

Reputation: 245

How do I deserialize this JSON using Jackson?

I have json that looks like this:

{
    "summary":{
        "somefield1":"somevalue1",
        "Twilio":{
            "field1":"value1",
            "field2":"value2"
        },
        "Tropo":{
            "field1":"value1",
            "field2":"value2"
        },
        ...
    }
}

I would like to deserialize it into a java class that looks like this:

public class Summary {
    private String someField1;
    private List<Vendor> vendors;
}

public class Vendor {
    private String name;
    private String field1;
    private String field2;
}

So the Twilio and Tropo need to become Vendor objects in a list where Vendor.name == "Twilio" or "Tropo".

I'm sure jackson has the tools I need to work with this structure but I've been striking out with web searches.

Upvotes: 0

Views: 174

Answers (3)

Michał Ziober
Michał Ziober

Reputation: 38710

You can do it with combination of @JsonRootName and @JsonAnySetter annotations. Your Summary class should look like this:

@JsonRootName("summary")
class Summary {

    @JsonProperty("somefield1")
    private String someField1;
    private List<Vendor> vendors = new ArrayList<Vendor>();

    @JsonAnySetter
    public void setDynamicProperty(String vendorName, Map<String, String> properties) {
        Vendor vendor = new Vendor();
        vendor.setName(vendorName);
        vendor.setField1(properties.get("field1"));
        vendor.setField2(properties.get("field2"));

        vendors.add(vendor);
    }

    //getters,setters,toString methods

}

Example usage:

ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);

System.out.println(mapper.readValue(json, Summary.class));

Above source code shows below string for your JSON:

Summary [someField1=somevalue1, vendors=[Vendor [name=Twilio, field1=value1, field2=value2], Vendor [name=Tropo, field1=value1, field2=value2]]]

Upvotes: 2

tom
tom

Reputation: 2712

The JSON structure you've got would match this java structure where the key of vendors is the vendor name.

public class Summary {
  private String someField1;
  private Map<String,Vendor> vendors;
}

public class Vendor {
  private String field1;
  private String field2;
}

The classes you've specified would support this JSON:

{
    "somefield1":"somevalue1",
    "vendors":[{
        "name":"Twilio"
        "field1":"value1",
        "field2":"value2"
    },
    {
        "name":"Tropo"
        "field1":"value1",
        "field2":"value2"
    },
    ...]

}

I don't think you can achieve what you want with jackson as the name is outside the "Vendor" object.

Upvotes: 0

Enrichman
Enrichman

Reputation: 11337

If you want to use your objects:

public class Summary {
    private String someField1;
    private List<Vendor> vendors;
}

public class Vendor {
    private String name;
    private String field1;
    private String field2;
}

you have to modify your json. Actually a structure like the one you defined will be converted to something like:

{
"summary": {
    "somefield1": "somevalue1",
    "vendors": [
        {
            "name": "Twilio",
            "field1": "value1",
            "field2": "value2"
        },
        {
            "name": "Tropo",
            "field1": "value1",
            "field2": "value2"
        }
    ]
}

}

a list is defined between the square brackets [], and in your case it's a list of objects {}.

I would change your json if you can, because the structure you post will be a mess to work with. The one I pointed out, that matches your java objects, is more clear.

Upvotes: 1

Related Questions