As a part of End to End REST Assured Tutorial, in this post, we will see how getter and setter methods of a POJO classes are related to serialization and deseriazation process.
A typical POJO class consists of private fields with its getter and setter methods or accessors (Which is not mandatory). You can have fields and accessors with any access level in a POJO. In this post, we will see how presence and absence of getter or setter methods impacts serialization and deserialization process.
POJO with proper getter and setter methods
Below is a POJO class with some private properties and their public accessors i.e. getter and setter methods. I have put a print statement in all getter and setter methods just to show method calling during serialization and deserialization process.
package GameOfGetterSetterPOJO; import com.fasterxml.jackson.annotation.JsonInclude; public class EmployeePojoWithGetterSetterMethods { // private variables or data members of pojo class private String firstName; private String lastName; private String gender; private int age; private double salary; private boolean married; // Getter and setter methods public String getFirstName() { System.out.println("Getter - First Name : "+ firstName); return firstName; } public void setFirstName(String firstName) { System.out.println("Setter - First Name : "+ firstName); this.firstName = firstName; } public String getLastName() { System.out.println("Getter - Last Name : "+ lastName); return lastName; } public void setLastName(String lastName) { System.out.println("Setter - Last Name : "+ lastName); this.lastName = lastName; } public String getGender() { System.out.println("Getter - Gender : "+ gender); return gender; } public void setGender(String gender) { System.out.println("Setter - Gender : "+ gender); this.gender = gender; } public int getAge() { System.out.println("Getter - Age : "+ age); return age; } public void setAge(int age) { System.out.println("Setter - Age : "+ age); this.age = age; } public double getSalary() { System.out.println("Getter - Salary : "+ salary); return salary; } public void setSalary(double salary) { System.out.println("Setter - Salary : "+ salary); this.salary = salary; } public boolean getMarried() { System.out.println("Getter - Married : "+ married); return married; } public void setMarried(boolean married) { System.out.println("Setter - Married : "+ married); this.married = married; } }
Let’s serialize with the above POJO class.
@Test public void serializeWithBothGetterSetter() throws JsonProcessingException { // Just create an object of Pojo class EmployeePojoWithGetterSetterMethods employeePojoWithGetterSetterMethods = new EmployeePojoWithGetterSetterMethods(); employeePojoWithGetterSetterMethods.setFirstName("Amod"); employeePojoWithGetterSetterMethods.setLastName("Mahajan"); employeePojoWithGetterSetterMethods.setAge(29); employeePojoWithGetterSetterMethods.setGender("Male"); employeePojoWithGetterSetterMethods.setSalary(12323.56); employeePojoWithGetterSetterMethods.setMarried(false); // Converting a Java class object to a JSON payload as string System.out.println("Serialization..."); ObjectMapper objectMapper = new ObjectMapper(); String employeeJson = objectMapper.writerWithDefaultPrettyPrinter() .writeValueAsString(employeePojoWithGetterSetterMethods); System.out.println(employeeJson); }
Output
Setter - First Name : Amod Setter - Last Name : Mahajan Setter - Age : 29 Setter - Gender : Male Setter - Salary : 12323.56 Setter - Married : false Serialization... Getter - First Name : Amod Getter - Last Name : Mahajan Getter - Gender : Male Getter - Age : 29 Getter - Salary : 12323.56 Getter - Married : false { "firstName" : "Amod", "lastName" : "Mahajan", "gender" : "Male", "age" : 29, "salary" : 12323.56, "married" : false }
Since we are calling setter methods to set values of properties so setter methods are executed. While serializing, getter methods are called internally as you can see in the output. That seems to be very obvious as to form a JSON they need a value of fields that can be retrieved using getter methods.
Let’s deserialize with the above POJO class.
@Test public void deserializeWithBothGetterSetter() throws JsonProcessingException { String jsonString = "{\r\n" + " \"firstName\" : \"Amod\",\r\n" + " \"lastName\" : \"Mahajan\",\r\n" + " \"gender\" : \"Male\",\r\n" + " \"age\" : 29,\r\n" + " \"salary\" : 12323.56,\r\n" + " \"married\" : false\r\n" + "}"; System.out.println("Deserialization..."); ObjectMapper objectMapper = new ObjectMapper(); EmployeePojoWithGetterSetterMethods employeePojoWithGetterSetterMethods = objectMapper.readValue(jsonString, EmployeePojoWithGetterSetterMethods.class); System.out.println("First name :- "+employeePojoWithGetterSetterMethods.getFirstName()); System.out.println("Last name :- "+employeePojoWithGetterSetterMethods.getLastName()); System.out.println("Age :- "+employeePojoWithGetterSetterMethods.getAge()); System.out.println("Gender :- "+employeePojoWithGetterSetterMethods.getGender()); System.out.println("Salary :- "+employeePojoWithGetterSetterMethods.getSalary()); System.out.println("Married :- "+employeePojoWithGetterSetterMethods.getMarried()); }
Output
Deserialization... Setter - First Name : Amod Setter - Last Name : Mahajan Setter - Gender : Male Setter - Age : 29 Setter - Salary : 12323.56 Setter - Married : false Getter - First Name : Amod First name :- Amod Getter - Last Name : Mahajan Last name :- Mahajan Getter - Age : 29 Age :- 29 Getter - Gender : Male Gender :- Male Getter - Salary : 12323.56 Salary :- 12323.56 Getter - Married : false Married :- false
During deserialization, setter methods are called internally as you can see in output as well. To print values, we are explicitly calling getter methods which you can see in the output.
In short:-
Serialization uses Getter methods.
Deserialization uses Setter methods
Let’s see what happens when setter methods are absent.
POJO with only getter methods
I removed all the traditional setter methods of properties. We have just setter methods now in the POJO class.
package GameOfGetterSetterPOJO; public class EmployeeWithGetterMethodsOnly { // private variables or data members of pojo class private String firstName; private String lastName; private String gender; private int age; private double salary; private boolean married; // Getter methods only public String getFirstName() { System.out.println("Getter - First Name : "+ firstName); return firstName; } public String getLastName() { System.out.println("Getter - Last Name : "+ lastName); return lastName; } public String getGender() { System.out.println("Getter - Gender : "+ gender); return gender; } public int getAge() { System.out.println("Getter - Age : "+ age); return age; } public double getSalary() { System.out.println("Getter - Salary : "+ salary); return salary; } public boolean getMarried() { System.out.println("Getter - Married : "+ married); return married; } }
Let’s serialize with the above POJO class.
@Test public void serializeWithGetterOnly() throws JsonProcessingException { // Just create an object of Pojo class but we can set values as we do not have any setter methods EmployeeWithGetterMethodsOnly employeeWithGetterMethodsOnly = new EmployeeWithGetterMethodsOnly(); // Converting a Java class object to a JSON payload as string ObjectMapper objectMapper = new ObjectMapper(); String employeeJson = objectMapper.writerWithDefaultPrettyPrinter() .writeValueAsString(employeeWithGetterMethodsOnly); System.out.println("Serialization..."); System.out.println(employeeJson); }
Output
Getter - First Name : null Getter - Last Name : null Getter - Gender : null Getter - Age : 0 Getter - Salary : 0.0 Getter - Married : false Serialization... { "firstName" : null, "lastName" : null, "gender" : null, "age" : 0, "salary" : 0.0, "married" : false }
Since we do not have setter methods we can not serialize with expected values. All class level fields are initiaized with default values which will be used for serialization as you can see in output.
Let’s deserialize with the above POJO class.
@Test public void deserializeWithGetterOnly() throws JsonProcessingException { String jsonString = "{\r\n" + " \"firstName\" : \"Amod\",\r\n" + " \"lastName\" : \"Mahajan\",\r\n" + " \"gender\" : \"Male\",\r\n" + " \"age\" : 29,\r\n" + " \"salary\" : 12323.56,\r\n" + " \"married\" : false\r\n" + "}"; System.out.println("Deserialization..."); ObjectMapper objectMapper = new ObjectMapper(); EmployeeWithGetterMethodsOnly employeeWithGetterMethodsOnly = objectMapper.readValue(jsonString, EmployeeWithGetterMethodsOnly.class); System.out.println("First name :- "+employeeWithGetterMethodsOnly.getFirstName()); System.out.println("Last name :- "+employeeWithGetterMethodsOnly.getLastName()); System.out.println("Age :- "+employeeWithGetterMethodsOnly.getAge()); System.out.println("Gender :- "+employeeWithGetterMethodsOnly.getGender()); System.out.println("Salary :- "+employeeWithGetterMethodsOnly.getSalary()); System.out.println("Married :- "+employeeWithGetterMethodsOnly.getMarried()); }
Output
Deserialization... Getter - First Name : Amod First name :- Amod Getter - Last Name : Mahajan Last name :- Mahajan Getter - Age : 29 Age :- 29 Getter - Gender : Male Gender :- Male Getter - Salary : 12323.56 Salary :- 12323.56 Getter - Married : false Married :- false
Deserialization had no issues with the absence of setter methods. If you see deserialization example of POJO with both getter and setter methods, in output setter methods were called internally which is not the same case in this example.
In short:-
If you have only getter methods in POJO class, you can not serialize it with desired values but can deserialize it easily. You do not need dedicated setter methods for deserializing.
Let’s see what happens when the getter methods are absent.
POJO with only setter methods
package GameOfGetterSetterPOJO; public class EmployeePojoWithSetterMethodsOnly { // private variables or data members of pojo class private String firstName; private String lastName; private String gender; private int age; private double salary; private boolean married; // Setter methods public void setFirstName(String firstName) { System.out.println("Setter - First Name : "+ firstName); this.firstName = firstName; } public void setLastName(String lastName) { System.out.println("Setter - Last Name : "+ lastName); this.lastName = lastName; } public void setGender(String gender) { System.out.println("Setter - Gender : "+ gender); this.gender = gender; } public void setAge(int age) { System.out.println("Setter - Age : "+ age); this.age = age; } public void setSalary(double salary) { System.out.println("Setter - Salary : "+ salary); this.salary = salary; } public void setMarried(boolean married) { System.out.println("Setter - Married : "+ married); this.married = married; } }
Let’s serialize with the above POJO class.
@Test public void serializeWithSetterOnly() throws JsonProcessingException { // Just create an object of Pojo class EmployeePojoWithSetterMethodsOnly employeePojoWithSetterMethodsOnly = new EmployeePojoWithSetterMethodsOnly(); employeePojoWithSetterMethodsOnly.setFirstName("Amod"); employeePojoWithSetterMethodsOnly.setLastName("Mahajan"); employeePojoWithSetterMethodsOnly.setAge(29); employeePojoWithSetterMethodsOnly.setGender("Male"); employeePojoWithSetterMethodsOnly.setSalary(12323.56); employeePojoWithSetterMethodsOnly.setMarried(false); // Converting a Java class object to a JSON payload as string System.out.println("Serialization..."); ObjectMapper objectMapper = new ObjectMapper(); String employeeJson = objectMapper.writerWithDefaultPrettyPrinter() .writeValueAsString(employeePojoWithSetterMethodsOnly); System.out.println(employeeJson); }
Output
Setter - First Name : Amod Setter - Last Name : Mahajan Setter - Age : 29 Setter - Gender : Male Setter - Salary : 12323.56 Setter - Married : false Serialization... FAILED: serializeWithSetterOnly com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class GameOfGetterSetterPOJO.EmployeePojoWithSetterMethodsOnly and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77) at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1277) at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:400)
We got an exception stating “No serializer found” which is obvious as serialization looks for getter methods that are not available.
Let’s deserialize with the above POJO class.
@Test public void deserializeWithSetterOnly() throws JsonProcessingException { String jsonString = "{\r\n" + " \"firstName\" : \"Amod\",\r\n" + " \"lastName\" : \"Mahajan\",\r\n" + " \"gender\" : \"Male\",\r\n" + " \"age\" : 29,\r\n" + " \"salary\" : 12323.56,\r\n" + " \"married\" : false\r\n" + "}"; System.out.println("Deserialization..."); ObjectMapper objectMapper = new ObjectMapper(); EmployeePojoWithSetterMethodsOnly employeePojoWithSetterMethodsOnly = objectMapper.readValue(jsonString, EmployeePojoWithSetterMethodsOnly.class); }
Output
Deserialization... Setter - First Name : Amod Setter - Last Name : Mahajan Setter - Gender : Male Setter - Age : 29 Setter - Salary : 12323.56
Since we do not have getter methods so we can not retrieve values of properties but that does not mean that properties are not initialized. Let’s add other getter methods to fetch values.
package GameOfGetterSetterPOJO; public class EmployeePojoWithSetterMethodsOnly { // private variables or data members of pojo class private String firstName; private String lastName; private String gender; private int age; private double salary; private boolean married; // Setter methods public void setFirstName(String firstName) { System.out.println("Setter - First Name : "+ firstName); this.firstName = firstName; } public void setLastName(String lastName) { System.out.println("Setter - Last Name : "+ lastName); this.lastName = lastName; } public void setGender(String gender) { System.out.println("Setter - Gender : "+ gender); this.gender = gender; } public void setAge(int age) { System.out.println("Setter - Age : "+ age); this.age = age; } public void setSalary(double salary) { System.out.println("Setter - Salary : "+ salary); this.salary = salary; } public void setMarried(boolean married) { System.out.println("Setter - Married : "+ married); this.married = married; } public String alternateGetFirstName() { return firstName; } public String alternateGetLastName() { return lastName; } public String alternateGetGender() { return gender; } public int alternateGetAge() { return age; } public double alternateGetSalary() { return salary; } public boolean alternateGetMarried() { return married; } }
Updated deserialize code
@Test public void deserializeWithSetterOnly() throws JsonProcessingException { String jsonString = "{\r\n" + " \"firstName\" : \"Amod\",\r\n" + " \"lastName\" : \"Mahajan\",\r\n" + " \"gender\" : \"Male\",\r\n" + " \"age\" : 29,\r\n" + " \"salary\" : 12323.56,\r\n" + " \"married\" : false\r\n" + "}"; System.out.println("Deserialization..."); ObjectMapper objectMapper = new ObjectMapper(); EmployeePojoWithSetterMethodsOnly employeePojoWithSetterMethodsOnly = objectMapper.readValue(jsonString, EmployeePojoWithSetterMethodsOnly.class); System.out.println("First name :- "+employeePojoWithSetterMethodsOnly.alternateGetFirstName()); System.out.println("Last name :- "+employeePojoWithSetterMethodsOnly.alternateGetLastName()); System.out.println("Age :- "+employeePojoWithSetterMethodsOnly.alternateGetAge()); System.out.println("Gender :- "+employeePojoWithSetterMethodsOnly.alternateGetGender()); System.out.println("Salary :- "+employeePojoWithSetterMethodsOnly.alternateGetSalary()); System.out.println("Married :- "+employeePojoWithSetterMethodsOnly.alternateGetMarried()); }
Output
Deserialization... Setter - First Name : Amod Setter - Last Name : Mahajan Setter - Gender : Male Setter - Age : 29 Setter - Salary : 12323.56 Setter - Married : false First name :- Amod Last name :- Mahajan Age :- 29 Gender :- Male Salary :- 12323.56 Married :- false
So if you have only setter methods then you can not serialize even you have any alternative getter methods. With setter methods, you can deserialize it easily but you need alternate getter methods to retrieve values.
If you do not have traditional or intended getter methods then you can not serialize and deserialize it.
You can download/clone the above sample project from here.
If you have any doubt, feel free to comment below.
If you like my posts, please like, comment, share and subscribe.
#ThanksForReading
#HappyLearning
Find all Selenium related posts here, all API manual and automation related posts here, and find frequently asked Java Programs here.
Many other topics you can navigate through the menu.
Can we deserialize an object even if there are no getter and setter methods?
Can deserialization happen even if there are no getter and setter methods?