Search code examples
javajsonjacksonfasterxml

How to use Jackson Annotation to do a mapping


Simply I have a POJO like this:

@JsonInclude(value=Include.NON_EMPTY)
public class Contact {

    @JsonProperty("email")
    private String email;
    @JsonProperty("firstName")
    private String firstname;
    @JsonIgnore
    private String subscriptions[];
...
}

When I create the JSON object using the JsonFactory and ObjectMapper, it would be something like:

{"email":"test@test.com","firstName":"testName"}

Now, the question is how can I generate something like the following without manual mapping.

{"properties": [
     {"property": "email", "value": "test@test.com"},
     {"property": "firstName", "value": "testName"}
 ]}

Note that, I know how to do manual mapping. Also, I need to use some features like Include.NON_EMPTY.


Solution

  • You can implement two steps processing as follows.

    Firstly, you convert your bean instance to a JsonNode instance using ObjectMapper. This guaranties applying all the Jackson annotations and customization. Secondly, you manually map the JsonNode fields to your "property-object" model.

    Here is an example:

    public class JacksonSerializer {
    
    public static class Contact {
        final public String email;
        final public String firstname;
        @JsonIgnore
        public String ignoreMe = "abc";
    
        public Contact(String email, String firstname) {
            this.email = email;
            this.firstname = firstname;
        }
    }
    
    public static class Property {
        final public String property;
        final public Object value;
    
        public Property(String property, Object value) {
            this.property = property;
            this.value = value;
        }
    }
    
    public static class Container {
        final public List<Property> properties;
    
        public Container(List<Property> properties) {
            this.properties = properties;
        }
    }
    
    public static void main(String[] args) throws JsonProcessingException {
        Contact contact = new Contact("abc@gmail.com", "John");
        ObjectMapper mapper = new ObjectMapper();
        JsonNode node = mapper.convertValue(contact, JsonNode.class);
        Iterator<String> fieldNames = node.fieldNames();
        List<Property> list = new ArrayList<>();
        while (fieldNames.hasNext()) {
            String fieldName = fieldNames.next();
            list.add(new Property(fieldName, node.get(fieldName)));
        }
        System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(new Container(list)));
    }
    

    }

    Output:

    { "properties" : [ {
    "property" : "email",
    "value" : "abc@gmail.com"
    }, {
    "property" : "firstname",
    "value" : "John"
    } ] }
    

    With a little effort you can re-factor the example to a custom serializer which can be plugged as documented here.