简体   繁体   中英

Map nested json values to a single POJO jackson-databind

I have a json which is required to be mapped into a single flat POJO object. I am using jackson-databind and seems like that does not support these type of operations. Any suggestion ?

{
  "id": 1,
  "name": "Alex",
  "emailId": "alex@gmail.com",
  "address": {
    "address": "21ST & FAIRVIEW AVE",
    "district": "district",
    "city": "EATON",
    "region": "PA",
    "postalCode": "18044",
    "country": "US"
  }

}

public class singlePojo{

String id;
String name;
String emailId;
String address;
String district;
String city;
String region;
String postalCode;

}

Use @JsonAnyGetter for mapping address

The @JsonAnyGetter annotation allows the flexibility of using a Map field as standard properties.

public class singlePojo{

String id;
String name;
String emailId;

Map<String,Object> address;

@JsonAnyGetter
public Map<String, Object> getAddress() {
    return address;
}

}

If you serialize this class the output will be

{
 "id": 1,
 "name": "Alex",
 "emailId": "alex@gmail.com",
 "address": "21ST & FAIRVIEW AVE",
 "district": "district",
 "city": "EATON",
 "region": "PA",
 "postalCode": "18044",
 "country": "US"
}

You can create a custom setter in your POJO using @JsonProperty that flattens the map into the individual fields:

@SuppressWarnings("unchecked")
@JsonProperty("address")
public void setDistrict(Map<String,String> map) {
    Map<String,String> address = map.get("address");
    this.district = address.get("district");
}

You'd have to do this for each field in the POJO that comes from the map, so it could be verbose and repetitive.

You could also use a custom deserializer that can do all the fields at once:

public class SimplePojoDeserializer extends StdDeserializer<SimplePojo> {
    @Override
    public SimplePojo deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {

        JsonNode node = jp.getCodec().readTree(jp);
        SimplePojo pojo = new SimplePojo();
        product.setAddress(node.get("address").get("address").textValue());
        product.setDistrict(node.get("address").get("district").textValue());
        // ...     
        return pojo;
    }
}

In this case you'd have to do all fields in your POJO, not just the address fields.

Some more details here .

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