How to map a nested value to a property using Jackson annotations?

The best is to use setter methods:

JSON:

...
 "coordinates": {
               "lat": 34.018721,
               "lng": -118.489090
             }
...

setter method for lat or lng will look like:

 @JsonProperty("coordinates")
    public void setLng(Map<String, String> coordinates) {
        this.lng = (Float.parseFloat(coordinates.get("lng")));
 }

if you need to read both (as you normally would do) then use a custom method

@JsonProperty("coordinates")
public void setLatLng(Map<String, String> coordinates){
    this.lat = (Float.parseFloat(coordinates.get("lat")));
    this.lng = (Float.parseFloat(coordinates.get("lng")));
}

This is how I handled this problem:

Brand class:

package org.answer.entity;

public class Brand {

    private Long id;

    private String name;

    public Brand() {

    }

    //accessors and mutators
}

Product class:

package org.answer.entity;

import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonSetter;

public class Product {

    private Long id;

    private String name;

    @JsonIgnore
    private Brand brand;

    private String brandName;

    public Product(){}

    @JsonGetter("brandName")
    protected String getBrandName() {
        if (brand != null)
            brandName = brand.getName();
        return brandName;
    }

    @JsonSetter("brandName")
    protected void setBrandName(String brandName) {
        if (brandName != null) {
            brand = new Brand();
            brand.setName(brandName);
        }
        this.brandName = brandName;
    }

//other accessors and mutators
}

Here, the brand instance will be ignored by Jackson during serialization and deserialization, since it is annotated with @JsonIgnore.

Jackson will use the method annotated with @JsonGetter for serialization of java object into JSON format. So, the brandName is set with brand.getName().

Similarly, Jackson will use the method annotated with @JsonSetter for deserialization of JSON format into java object. In this scenario, you will have to instantiate the brand object yourself and set its name property from brandName.

You can use @Transient persistence annotation with brandName, if you want it to be ignored by persistence provider.


You can achieve this like that:

String brandName;

@JsonProperty("brand")
private void unpackNameFromNestedObject(Map<String, String> brand) {
    brandName = brand.get("name");
}

You can use JsonPath-expressions to map nested properties. I don't think there's any official support (see this issue), but there's an unofficial implementation here: https://github.com/elasticpath/json-unmarshaller

Tags:

Java

Json

Jackson