Jackson : JSON Selective serialize/deserialize object properties
While serializing java objects to JSON and deserializing JSON to Java Objects, sometimes one would want to ignore the property only while serializing but allow the property to be deserialized into Java object property. On a similar note there can be a requirement where a property has to be ignored only while deserializing into java object property but the property has to be allowed to be serialized.

Suppose we have a backend service in an application which stores the Customer details of the application like name,telephone,password etc.Supposing the Customer object structure to be below.

public class Customer {

private String name;

private String customerTelephone;

private String password;

private String welcomeMessage;



public String getName() {

return name;

}



public void setName(String name) {

this.name = name;

}



public String getCustomerTelephone() {

return customerTelephone;

}



public void setCustomerTelephone(String customerTelephone) {

this.customerTelephone = customerTelephone;

}



public String getPassword() {

return password;

}



public void setPassword(String password) {

this.password = password;

}



public String getWelcomeMessage() {

return welcomeMessage;

}



public void setWelcomeMessage(String welcomeMessage) {

this.welcomeMessage = welcomeMessage;

}



}

Supposing there is a rest API endpoint the application which retrieves the data associated with the customer from database. While sending the customer data in the response to the API consumer We would want to serialize(send) all the details of the customer except sensitive information like password.But the password field should be able to be deserialized into java object field for rest API endpoint that allows updating password field of the customer.

This password field has to be allowed only for deserialization but should not be allowed to be serialized.

Imagine the rest API endpoint for retrieving the customer details has the welcome message to the customer. This welcome message that is sent in the response of the API call has to be allowed only for serialization but not for deserialization into java object.

Below is the rest endpoints for the customer details service

@RestController

public class CustomerController {



@GetMapping("/customerdetail/{name}")

public Customer getCustomerDetail(@PathVariable("name")String customerName){

Customer customer = new Customer();

customer.setName(customerName);

customer.setCustomerTelephone("1234");

customer.setPassword("password_to_be_ignored_while_serialization");

customer.setWelcomeMessage("Welcome to my world "+customerName);

return customer;

}



@PostMapping("/customerdetail/update")

public Customer updateCustomerDetail(@RequestBody Customer customer){

System.out.println("Customer Name:"+customer.getName());

System.out.println("Customer Telephone:"+customer.getCustomerTelephone());

System.out.println("Password:"+customer.getPassword());

System.out.println("Welcome message:"+customer.getWelcomeMessage());

return customer;

}

This requirement for allowing the property only during serialization/deserialization can be achieved using Jackson annotation @JsonProperty parameter for access.

If we add the annotation with the appropriate value for the access. we can achieve selective serialization/deserialization only but not allowed to be deserialized/serialized respectively.



private String name;

private String customerTelephone;



private String password;



private String welcomeMessage; public class Customer {private String name;private String customerTelephone; @JsonProperty (access = JsonProperty.Access.WRITE_ONLY)private String password; @JsonProperty (access = JsonProperty.Access.READ_ONLY)private String welcomeMessage; public String getName() {

return name;

} public void setName(String name) {

this.name = name;

} public String getCustomerTelephone() {

return customerTelephone;

} public void setCustomerTelephone(String customerTelephone) {

this.customerTelephone = customerTelephone;

} public String getPassword() {

return password;

} public void setPassword(String password) {

this.password = password;

} public String getWelcomeMessage() {

return welcomeMessage;

} public void setWelcomeMessage(String welcomeMessage) {

this.welcomeMessage = welcomeMessage;

} }

@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)

Annotating the password variable with the above will allow the field to be only deserialized but ignored while serializing.

Annotating the welcome message variable with the above will allow the field to be only serialized but ignored while deserializing.

Let us try to consume the rest API endpoint and see the result.

The welcome message field is ignored during deserialization into java object but the other fields like password etc are all deserialized to java object.

Consuming the rest end point for retrieving customer details

As you can see from the API response password field is ignored to be serialized whereas all other fields like welcome message got successfully serialized.

This way we have achieved the welcome message field to be allowed only for serialization and be ignored while deserialization. and password field is allowed only while deserialization and ignored while serialization.

Please visit my YouTube channel https://youtube.com/channel/UC-8tqCyhtt6Lt5-n2UMZB_A
['Sai Pitchuka']
['JavaScript', 'Spring Boot', 'Java', 'Json']