Serialization – How to create JSON Payload from Java Object – Jackson API

HOME

In this tutorial, I will explain the creation of JSON Object Payload with the help of POJO (Plain Old Java Object).

What is POJO?

POJO stands for Plain Old Java Object. It is a very simple object, and it has no bounds or we can say that it has no restrictions other than the Java language specification. Also, it does not require any classpath.

A big advantage of POJO is it increases the readability and reusability of our project code and developers find it easy when understanding the code. Also, POJO is easy to write and anyone can understand them easily.

Now let’s deep dive into some technical terms about the POJO. Below are a few points about the POJO are:

  1. A POJO should not have to extend prespecified classes.
  2. Secondly, a POJO should not have implemented any prespecified interface.
  3. Lastly, POJO should not contain prespecified annotations

A POJO class can follow some rules for better usability. These rules are:-

  1. Each variable should be declared as private just to restrict direct access.
  2. Each variable that needs to be accessed outside class may have a getter, a setter, or both methods. If the value of a field is stored after some calculations, then we must not have any setter method for that.
  3. It Should have a default public constructor.
  4. Can override toString(), hashcode, and equals() methods.

POJO classes are extensively used for creating JSON and XML payloads for API.

In the below example, let me create a simple JSON with some nodes which is actually a 1:1 mapping i.e. each key has a single value, and the type of values is mixed.

{
  "firstName" : "Vibha",
  "lastName" : "Singh",
  "age" : 30,
  "salary" : 75000.0,
  "designation" : "Manager",
  "contactNumber" : "+91999996712",
  "emailId" : "abc123@test.com"
}

Let us create variables in the POJO class now for the above JSON. Now, a class name Employee will be created with the private data members as mentioned in the above JSON. Since we have created all variables as private, then there should be a way to manipulate or retrieve these data. So we create the corresponding getter and setter methods for these data members.

It is very tedious to create getter and setter methods for all the data members for big JSON strings.  Every IDE gives you a shortcut to generate getter and setter methods.  Here, I am using Eclipse and creating these getter and setter methods.

Select all the data members and Right-click on the page. Then select Source and then select Generate Getter and Setter methods.

This opens a new screen as shown below.

You can select the data member for which you want to create the getter and setter method. I want to create the getter and setter methods for all the data members, so click on Select All and then click on the Generate Button. This will generate the getter and setter methods for all the data members.

Below is the sample code of the Employee table, which contains the data members needed for Employee JSON and their corresponding getter and setter methods.

public class Employee {

	// private variables or data members of POJO class
	private String firstName;
	private String lastName;
	private int age;
	private double salary;
	private String designation;
	private String contactNumber;
	private String emailId;

	// Getter and setter methods
	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}

	public String getDesignation() {
		return designation;
	}

	public void setDesignation(String designation) {
		this.designation = designation;
	}
	
	public String getContactNumber() {
		return contactNumber;
	}

	public void setContactNumber(String contactNumber) {
		this.contactNumber = contactNumber;
	}

	public String getEmailId() {
		return emailId;
	}

	public void setEmailId(String emailId) {
		this.emailId = emailId;
	}

}

Using the above POJO class, you can create any number of custom Employee objects and each object can be converted into a JSON Object and Each JSON object can be parsed into Employee POJO.

We will create a JSON object from POJO and vice versa now, which is generally called serialization and deserialization using Jackson APIs.

Serialization – Serialization is a process where you convert an Instance of a Class (Object of a class) into a Byte Stream. Here, we are converting Employee class object to JSON representation or Object

Deserialization – It is the reverse of serializing. In this process, we will read the Serialized byte stream from the file and convert it back into the Class instance representation. Here, we are converting a JSON Object to an Employee class object.

We are using Jackson API for Serialization and Deserialization. So, add the Jackson dependency to the project.

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.0</version>
</dependency>

What is ObjectMapper ?

ObjectMapper provides functionality for reading and writing JSON, either to and from basic POJOs (Plain Old Java Objects), or to and from a general-purpose JSON Tree Model (JsonNode), as well as related functionality for performing conversions. It is also highly customizable to work both with different styles of JSON content and to support more advanced object concepts such as polymorphism and object identity.

Now, let us create a Test Class to show Serialization.

public class EmployeeTest {

	@Test
	public void serializationTest()  {

		Employee employee = new Employee();
		employee.setFirstName("Vibha");
		employee.setLastName("Singh");
		employee.setAge(30);
		employee.setSalary(75000);
		employee.setDesignation("Manager");

		// Converting a Java class object to a JSON payload as string
		ObjectMapper mapper = new ObjectMapper();
		String employeeJson = mapper.writeValueAsString(employee);
		String employeePrettyJson = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(employee);
		System.out.println(employeeJson);
		System.out.println(employeePrettyJson);
   }
}try {
			String employeeJson = mapper.writeValueAsString(employee);
			System.out.println(employeeJson);
			String employeePrettyJson = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(employee);
			System.out.println(employeePrettyJson);
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}	
	}

The output of the above program is

Here, ObjectMapper from fasterxml.jackson.databind is used for Serialization.

writeValueAsString() is a method that can be used to serialize any Java value as a String.

writerWithDefaultPrettyPrinter() is used to pretty-print the JSON output. It is a Factory method for constructing ObjectWriter that will serialize objects using the default pretty printer for indentation.

I hope this has helped to clear your doubts regarding POJO and how to create JSON objects using POJO.

We are done! Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!!

How to pass authorization token in header in Rest assured?

HOME

 <dependencies>

       <!-- Rest Assured Dependency -->
      <dependency>
         <groupId>io.rest-assured</groupId>
        <artifactId>rest-assured</artifactId>
        <version>5.4.0</version>
        <scope>test</scope>
      </dependency>

        <!-- TestNG Dependency-->
      <dependency>
          <groupId>org.testng</groupId>
         <artifactId>testng</artifactId>
         <version>7.8.0</version>
         <scope>test</scope>
       </dependency>

</dependencies>

import io.restassured.http.ContentType;
import io.restassured.response.Response;
import org.testng.Assert;
import org.testng.annotations.Test;
import static io.restassured.RestAssured.given;

public class BasicAuth_Demo {


    @Test
    public void createUser() {
        Response response = given()
                .auth()
                .preemptive()
                .header("Authorization", "Token")
                .header("Accept", "application/json")
                .contentType(ContentType.JSON)
                .body(validRequest)
                .when()
                .post("http://localhost:8080/users")
                .then()
                .extract()
                .response();

        int statusCode = response.getStatusCode();

        Assert.assertEquals(statusCode,200);
    }
}

package org.example;

import io.restassured.http.ContentType;
import io.restassured.response.Response;
import org.junit.Before;
import org.junit.Test;

import static io.restassured.RestAssured.given;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;

public class BasicAuth_Demo {

    private static final String BASE_URL = "https://httpbin.org/basic-auth/user/pass";
    private static final String TOKEN = "Basic dXNlcjpwYXNz";

    @Before
    public void setup() {
        given().baseUri(BASE_URL);
    }

    @Test
    public void validateToken() {

        Response response = given()
                .header("Accept", "application/json")
                .header("Authorization",TOKEN)
                .contentType(ContentType.JSON)
                .when()
                .get("https://httpbin.org/basic-auth/user/pass")
                .then()
                .log().all()
                .extract()
                .response();

        assertThat(response.getStatusCode(),equalTo(200));

    }

}

Marshalling- How to convert Java Objects to XML using JAXB

HOME

This tutorial explains how to use JAXB (Java Architecture for XML Binding) to convert Java Objects to XML documents.

JAXB provides a fast and convenient way to marshal (write) Java Objects into XML and un-marshal (read) XML into Java Objects. It supports a binding framework that maps XML elements and attributes to Java fields and properties using Java annotations.

With Java releases lower than Java 11, JAXB was part of the JVM and you could use it directly without defining additional libraries.

As of Java 11, JAXB is not part of the JRE anymore, and you need to configure the relevant libraries via your dependency management system, for example, either Maven or Gradle.

Configure the Java compiler level to be at least 11 and add the JAXB dependencies to your pom file.

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>JAXBDemo</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <name>JAXBDemo</name>
  <url>http://www.example.com</url>

  <properties>  
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.plugin.version>3.11.0</maven.compiler.plugin.version>
    <maven.surefire.plugin.version>3.2.1</maven.surefire.plugin.version>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.2</version>
      <scope>test</scope>
  </dependency>
    
 <dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>4.0.4</version>
   </dependency>
 </dependencies>
   
<build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${maven.surefire.plugin.version}</version>
        <configuration>
          <testFailureIgnore>true</testFailureIgnore>
        </configuration>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${maven.compiler.plugin.version}</version>
        <configuration>
          <source>${maven.compiler.source}</source>
          <target>${maven.compiler.target}</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

JAXB Annotations

  1. @XmlRootElement: Define the root element for an XML tree
  2. @XmlType: Define the order in which the fields are written in the XML file
  3. @XmlElement: Define the actual XML element name which will be used
  4. @XmlAttribute: Define the id field is mapped as an attribute instead of an element
  5. @XmlTransient: Annotate fields that we don’t want to be included in XML

Sample XML Structure

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<EmployeeDetails>
    <firstName>Vibha</firstName>
    <lastName>Singh</lastName>
    <gender>female</gender>
    <age>30</age>
    <maritalStatus>married</maritalStatus>
    <designation>Manager</designation>
    <contactNumber>+919999988822</contactNumber>
    <emailId>abc@test.com</emailId>
    <GrossSalary>75000.0</GrossSalary>
</EmployeeDetails>

Marshalling

Marshalling provides a client application the ability to convert a JAXB derived Java object tree into XML data.

Let’s see the steps to convert Java Objects into XML document.

  1. Create POJO Class of XML
  2. Create the JAXBContext object
  3. Create the Marshaller objects
  4. Create the content tree by using set methods
  5. Call the marshal method

Now, let us create the Java Objects (POJO).

import jakarta.xml.bind.annotation.*;

@XmlRootElement(name = "EmployeeDetails")
@XmlAccessorType(XmlAccessType.FIELD)

//Define the order in which the fields are written in XML
@XmlType(propOrder = { "firstName", "lastName", "gender", "age", "maritalStatus", "designation", "contactNumber",
		"emailId", "salary" })

public class Employee {

	private String firstName;
	private String lastName;
	private int age;

    @XmlElement(name = "GrossSalary")
	private double salary;
	private String designation;
	private String contactNumber;
	private String emailId;
	private String gender;
	private String maritalStatus;

	// Getter and setter methods
	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}

	public String getDesignation() {
		return designation;
	}

	public void setDesignation(String designation) {
		this.designation = designation;
	}

	public String getContactNumber() {
		return contactNumber;
	}

	public void setContactNumber(String contactNumber) {
		this.contactNumber = contactNumber;
	}

	public String getEmailId() {
		return emailId;
	}

	public void setEmailId(String emailId) {
		this.emailId = emailId;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public String getMaritalStatus() {
		return maritalStatus;
	}

	public void setMaritalStatus(String maritalStatus) {
		this.maritalStatus = maritalStatus;
	}

   @Override
	public String toString() {
		return "Employee [FirstName=" + firstName + ", LastName=" + lastName + ", Age=" + age + ", Salary=" + salary
				+ ", Designation=" + designation + ", ContactNumber=" + contactNumber + ", EmailId=" + emailId
				+ ", Gender=" + gender + ", MaritalStatus=" + maritalStatus + "]";
	}
}

Create the following test program for writing the XML file.

import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Marshaller;
import jakarta.xml.bind.PropertyException;
import org.junit.Test;
import java.io.StringWriter;

public class SerializationDemo {

    @Test
    public void serializationTest1() {

        try {

            Employee employee = new Employee();

            employee.setFirstName("Terry");
            employee.setLastName("Mathew");
            employee.setAge(30);
            employee.setSalary(75000);
            employee.setDesignation("Manager");
            employee.setContactNumber("+919999988822");
            employee.setEmailId("abc@test.com");
            employee.setMaritalStatus("married");
            employee.setGender("female");

            // Create JAXB Context
            JAXBContext context = JAXBContext.newInstance(Employee.class);

            // Create Marshaller
            Marshaller jaxbMarshaller = context.createMarshaller();

            // Required formatting
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

            // Write XML to StringWriter
            StringWriter sw = new StringWriter();
            jaxbMarshaller.marshal(employee, sw);

            // Convert XML to String
            String xmlContent = sw.toString();
            System.out.println(xmlContent);

        } catch (PropertyException e) {
            e.printStackTrace();

        } catch (JAXBException e) {
            e.printStackTrace();
        }
    }
}

When we run the code above, we may check the console output to verify that we have successfully converted Java object to XML:

By default, the Marshaller uses UTF-8 encoding when generating XML data.

The javax.xml.bind.JAXBContext class provides a client’s entry point to JAXB API. By default, JAXB does not format the XML document. This saves space and prevents that any white-space may accidentally be interpreted as significant.

To have JAXB format the output, we simply set the Marshaller.JAXB_FORMATTED_OUTPUT property to true on the Marshaller. The marshal method uses an object and an output file where to store the generated XML as parameters.

You can see that we have used JAXB Annotations like @XMLRootElement are changed from Employee to EmployeeDetails.

The order of elements in the XML is defined by

@XmlType(propOrder = { "firstName", "lastName", "gender", "age", "maritalStatus", "designation", "contactNumber","emailId", "salary" })

@XMLElement has set the element name to GrossSalary from Salary.

The below example is the short way of writing the same test and saving XML. We need to add a constructor in the POJO class so that we can set the values to the variables through the Constructor.

import jakarta.xml.bind.annotation.*;

@XmlRootElement(name = "EmployeeDetails")
@XmlAccessorType(XmlAccessType.FIELD)

//Define the order in which the fields are written in XML
@XmlType(propOrder = { "firstName", "lastName", "gender", "age", "maritalStatus", "designation", "contactNumber",
        "emailId", "salary" })

public class Employee {

    private String firstName;
    private String lastName;
    private int age;

    @XmlElement(name = "GrossSalary")
    private double salary;
    private String designation;
    private String contactNumber;
    private String emailId;
    private String gender;
    private String maritalStatus;

    public Employee() {
        super();

    }

    public Employee(String firstName, String lastName, int age, double salary, String designation, String contactNumber,
                    String emailId, String gender, String maritalStatus) {

        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;


        this.salary = salary;

        this.designation = designation;
        this.contactNumber = contactNumber;
        this.emailId = emailId;
        this.gender = gender;
        this.maritalStatus = maritalStatus;
    }

    // Getter and setter methods
    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public String getDesignation() {
        return designation;
    }

    public void setDesignation(String designation) {
        this.designation = designation;
    }

    public String getContactNumber() {
        return contactNumber;
    }

    public void setContactNumber(String contactNumber) {
        this.contactNumber = contactNumber;
    }

    public String getEmailId() {
        return emailId;
    }

    public void setEmailId(String emailId) {
        this.emailId = emailId;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getMaritalStatus() {
        return maritalStatus;
    }

    public void setMaritalStatus(String maritalStatus) {
        this.maritalStatus = maritalStatus;
    }

    @Override
    public String toString() {
        return "Employee [FirstName=" + firstName + ", LastName=" + lastName + ", Age=" + age + ", Salary=" + salary
                + ", Designation=" + designation + ", ContactNumber=" + contactNumber + ", EmailId=" + emailId
                + ", Gender=" + gender + ", MaritalStatus=" + maritalStatus + "]";
    }
}

The below JAXB example for XML marshalling convert Java objects into an XML.

import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Marshaller;
import jakarta.xml.bind.PropertyException;
import org.junit.Test;
import java.io.File;
import java.io.StringWriter;

public class SerializationDemo {


    @Test
    public void serializationTest2() {

        try {

            Employee employee = new Employee("Thomas", "Pawsey", 35, 100000, "Director", "+919999988822","Test@test.com", "married", "female");

            // Create JAXB Context
            JAXBContext context = JAXBContext.newInstance(Employee.class);

            // Create Marshaller
            Marshaller jaxbMarshaller = context.createMarshaller();

            // Required formatting
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

            // Write XML to StringWriter
            StringWriter writer = new StringWriter();
            jaxbMarshaller.marshal(employee, writer);

            // Convert XML to String
            String xmlContent = writer.toString();
            System.out.println(xmlContent);

            // Save the file
            String userDir = System.getProperty("user.dir");
            jaxbMarshaller.marshal(employee, new File(userDir + "\\src\\test\\resources\\JAXB_XML.xml"));
            System.out.println("File is saved");
            
        } catch (PropertyException e) {
            e.printStackTrace();

        } catch (JAXBException e) {
            e.printStackTrace();
        }
    }
}

When we run the code above, we may check the console output to verify that we have successfully converted Java object to XML:

The XML is saved under src/test/resources. To see this file, after the execution of the test, you need to refresh the project.

Similarly, we can unmarshal an XML to Java Objects in the next tutorial.

We are done! Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!!

Jackson Annotations for XML – JacksonXmlRootElement

HOME

The Jackson XML module adds some additional support for XML-specific features, just like JSON has some additional features. These annotations allow us to control the XML namespace and local name for elements, including the root element, whether a field is rendered in an element or as plain text, whether the content of an element is rendered in a CData wrapper, and whether a collection should use a wrapper element or not.

We need to add Jackson XML dependency to the project.

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.17.2</version>
</dependency>

It is used to define the name of the root element used for the root-level object when serialized, which normally uses the name of the type (class). This can only adjust the Namespace and Local name – since the root element can never be serialized as an attribute.

@JacksonXmlRootElement(localName = "Employee_Details")

Below is the example of JacksonXmlRootElement.

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;

@JacksonXmlRootElement(localName = "Employee_Details")
public class Employee {

    // Data members of POJO class
    private String firstName;
    private String lastName;
    private int age;
    private double salary;
    private String designation;
    private String contactNumber;
    private String emailId;
    private String gender;
    private String maritalStatus;

    // Getter and setter methods
    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public String getDesignation() {
        return designation;
    }

    public void setDesignation(String designation) {
        this.designation = designation;
    }

    public String getContactNumber() {
        return contactNumber;
    }

    public void setContactNumber(String contactNumber) {
        this.contactNumber = contactNumber;
    }

    public String getEmailId() {
        return emailId;
    }

    public void setEmailId(String emailId) {
        this.emailId = emailId;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getMaritalStatus() {
        return maritalStatus;
    }

    public void setMaritalStatus(String maritalStatus) {
        this.maritalStatus = maritalStatus;
    }

}

Let us create a test to build an XML.

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.junit.Test;

public class EmployeeXMLTest {

    @Test
    public void serializationTest() {

        // Create an object of POJO class
        Employee employee = new Employee();

        employee.setFirstName("Vibha");
        employee.setLastName("Singh");
        employee.setAge(35);
        employee.setSalary(135000);
        employee.setDesignation("Manager");
        employee.setContactNumber("+919999988822");
        employee.setEmailId("abc@test.com");
        employee.setMaritalStatus("married");
        employee.setGender("female");

        // Converting a Java class object to XML
        XmlMapper xmlMapper = new XmlMapper();

        try {
            String employeeXml = xmlMapper.writerWithDefaultPrettyPrinter().writeValueAsString(employee);
            System.out.println(employeeXml);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

    }
}

The output of the above program is

You can see here that localName of XML is Employee_Details, not Employee.

@JacksonXmlRootElement(namespace = "urn:request:jacksonxml", localName = "Employee_Details")

The XML is shown below.

Hope this helps to understand @JacksonXmlRootElement.

We are done! Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!!

Deserialization – How to convert XML to Java Objects using Jackson API

HOME

The previous tutorials have explained the conversion of Java Objects to XML using Jackson API. This tutorial explains parsing the XML document to Java objects using Jackson API.

To parse the XML, we will use the Jackson library. Use the latest Jackson library.

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.16.0</version>
</dependency>

Jackson allows us to read the contents of an XML file and deserialize the XML back into a Java object. In our example, we will read an XML document containing details about an Employee, and use Jackson to extract this data and use it to create Java objects containing the same information.

First, let us create an XML document matching our class to read from.

Create deserialize.xml with the following contents:

<Employee>
  <firstName>Vibha</firstName>
  <lastName>Singh</lastName>
  <age>35</age>
  <salary>135000.0</salary>
  <designation>Manager</designation>
  <contactNumber>+919999988822</contactNumber>
  <emailId>abc@test.com</emailId>
  <gender>female</gender>
  <maritalStatus>married</maritalStatus>
</Employee>

Deserialization – It is the reverse of serializing. In this process, we will read the Serialized byte stream from the file and convert it back into the Class instance representation. Here, we are converting a XML to an Employee class object.

Let us add a deserializeFromXML() function to deserialize the XML file above into a Java object:

import com.fasterxml.jackson.core.exc.StreamReadException;
import com.fasterxml.jackson.databind.DatabindException;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.example.simple.Employee;
import org.junit.Test;

import java.io.File;
import java.io.IOException;

public class DeserializeXMLTest {
    @Test
    public void deserializeFromXML() {

        XmlMapper xmlMapper = new XmlMapper();
        String userDir = System.getProperty("user.dir");

        // Converting Employee XML to Employee class object
        try {
            Employee emp = xmlMapper.readValue(new File(userDir + "\\src\\test\\resources\\XMLExample.xml"),
                    Employee.class);

            System.out.println("Deserialized data: ");
            System.out.println("First Name of employee : " + emp.getFirstName());
            System.out.println("Last Name of employee : " + emp.getLastName());
            System.out.println("Age of employee : " + emp.getAge());
            System.out.println("Salary of employee : " + emp.getSalary());
            System.out.println("Designation of employee : " + emp.getDesignation());
            System.out.println("Contact Number of employee : " + emp.getContactNumber());
            System.out.println("EmailId of employee : " + emp.getEmailId());
            System.out.println("Marital Status of employee : " + emp.getMaritalStatus());
            System.out.println("Gender of employee : " + emp.getGender());

        } catch (StreamReadException e) {
            e.printStackTrace();
        } catch (DatabindException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

The output of the above program is shown below:

Manipulating Nested Elements in XML

Let us enhance our XML file to add nested elements and loops, and modify our code to deserialize the following updated structure.

<Employees>
  <name>
    <firtsname>John</firtsname>
    <middlename>Dave</middlename>
    <lastname>William</lastname>
  </name>
  <contactdetails>
    <deskNumber>00-428507</deskNumber>
    <mobileNumber>+917823561231</mobileNumber>
    <emergencyDetails>
      <emergency_no1>+91 1212898920</emergency_no1>
      <emergency_no2>+91 9997722123</emergency_no2>
      <emergency_no3>+91 8023881245</emergency_no3>
    </emergencyDetails>
  </contactdetails>
  <age>30</age>
  <salary>75000.0</salary>
  <designation>Manager</designation>
  <emailId>abc@test.com</emailId>
  <gender>female</gender>
  <maritalStatus>married</maritalStatus>
</Employees>

There will be a slight change in the deserializeFromXML() method for the nested XML Structure.

import com.fasterxml.jackson.core.exc.StreamReadException;
import com.fasterxml.jackson.databind.DatabindException;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.example.complex.Employees;
import org.example.simple.Employee;
import org.junit.Test;
import java.io.File;
import java.io.IOException;

public class DeserializeComplexXMLTest {
    @Test
    public void deserializeFromXML() {

        XmlMapper xmlMapper = new XmlMapper();

        String userDir = System.getProperty("user.dir");

        // Converting Employee XML to Employee class object
        try {
            Employees employee2 = xmlMapper
                    .readValue(new File(userDir + "\\src\\test\\resources\\NestedXMLExample.xml"), Employees.class);
            System.out.println("Deserialized data: ");
            System.out.println("First Name of employee : " + employee2.getName().getFirtsname());
            System.out.println("Middle Name of employee : " + employee2.getName().getMiddlename());
            System.out.println("Last Name of employee : " + employee2.getName().getLastname());
            System.out.println("Age of employee : " + employee2.getAge());
            System.out.println("Salary of employee : " + employee2.getSalary());
            System.out.println("Designation of employee : " + employee2.getDesignation());
            System.out.println("Desk Number of employee : " + employee2.getContactdetails().getDeskNumber());
            System.out.println("Mobile Number of employee : " + employee2.getContactdetails().getMobileNumber());
            System.out.println("Emergency Number1 of employee : "
                    + employee2.getContactdetails().getEmergencyDetails().getEmergency_no1());
            System.out.println("Emergency Number2 of employee : "
                    + employee2.getContactdetails().getEmergencyDetails().getEmergency_no2());
            System.out.println("Emergency Number3 of employee : "
                    + employee2.getContactdetails().getEmergencyDetails().getEmergency_no3());
            System.out.println("EmailId of employee : " + employee2.getEmailId());
            System.out.println("Gender of employee : " + employee2.getGender());
            System.out.println("Marital Status of employee : " + employee2.getMaritalStatus());

        } catch (StreamReadException e) {
            e.printStackTrace();
        } catch (DatabindException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

The output of the above program is shown below:

Here, you can see that when we need to serialize the nested attributes like Firstname, we have called the first Name class and then getFirstName().

System.out.println("First Name of employee : " + employee2.getName().getFirtsname());

To know about Serialization – Conversion of Java Objects to XML, you can refer to this tutorial – Serialization – How to convert Java Objects to XML using Jackson API.

We are done! Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!!

Serialization – How to convert Java Objects to XML using Jackson API

HOME

The previous tutorials have explained the conversion of Java Objects to JSON payload and vice versa, i.e. conversion of JSON payload to Java Objects using Jackson API.

This tutorial explains parsing the XML document to Java objects using Jackson API.

To parse the above XML, we will use the Jackson library. Use the latest Jackson Library.

<dependency>
      <groupId>com.fasterxml.jackson.dataformat</groupId>
      <artifactId>jackson-dataformat-xml</artifactId>
      <version>2.16.0</version>
</dependency>

We are going to parse the following XML.

<Employee>
  <firstName>Vibha</firstName>
  <lastName>Singh</lastName>
  <age>35</age>
  <salary>135000.0</salary>
  <designation>Manager</designation>
  <contactNumber>+919999988822</contactNumber>
  <emailId>abc@test.com</emailId>
  <gender>female</gender>
  <maritalStatus>married</maritalStatus>
</Employee>

We will create an XML from POJO and vice versa now, which is generally called serialization and deserialization using Jackson APIs.

XmlMapper is a subclass of ObjectMapper which is used in JSON serialization. However, it adds some XML-specific tweaks to the parent class.

XmlMapper xmlMapper = new XmlMapper();

We can now look at how to use it to do the actual serialization. Let’s create a Java class first:

Below is the sample code of the Employee table, which contains the data members needed for Employee XML and their corresponding getter and setter methods.

public class Employee {

	// Data members of POJO class
	private String firstName;
	private String lastName;
	private int age;
	private double salary;
	private String designation;
	private String contactNumber;
	private String emailId;
	private String gender;
	private String maritalStatus;

	// Getter and setter methods
	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}

	public String getDesignation() {
		return designation;
	}

	public void setDesignation(String designation) {
		this.designation = designation;
	}

	public String getContactNumber() {
		return contactNumber;
	}

	public void setContactNumber(String contactNumber) {
		this.contactNumber = contactNumber;
	}

	public String getEmailId() {
		return emailId;
	}

	public void setEmailId(String emailId) {
		this.emailId = emailId;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public String getMaritalStatus() {
		return maritalStatus;
	}

	public void setMaritalStatus(String maritalStatus) {
		this.maritalStatus = maritalStatus;
	}

}

Writing XML is done using the various writeValue() methods that Jackson exposes.

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.junit.Test;

public class EmployeeXMLTest {

    @Test
    public void serializationTest() {

        // Create an object of POJO class
        Employee employee = new Employee();

        employee.setFirstName("Vibha");
        employee.setLastName("Singh");
        employee.setAge(35);
        employee.setSalary(135000);
        employee.setDesignation("Manager");
        employee.setContactNumber("+919999988822");
        employee.setEmailId("abc@test.com");
        employee.setMaritalStatus("married");
        employee.setGender("female");

        // Converting a Java class object to XML
        XmlMapper xmlMapper = new XmlMapper();

        try {
            String employeeXml = xmlMapper.writerWithDefaultPrettyPrinter().writeValueAsString(employee);
            System.out.println(employeeXml);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

    }
}

The output of the above program is

Nested Elements in XML

Let us create a complex XML now as shown below.

<Employees>
  <name>
    <firtsname>John</firtsname>
    <middlename>Dave</middlename>
    <lastname>William</lastname>
  </name>
  <contactdetails>
    <deskNumber>00-428507</deskNumber>
    <mobileNumber>+917823561231</mobileNumber>
    <emergencyDetails>
      <emergency_no1>+91 1212898920</emergency_no1>
      <emergency_no2>+91 9997722123</emergency_no2>
      <emergency_no3>+91 8023881245</emergency_no3>
    </emergencyDetails>
  </contactdetails>
  <age>30</age>
  <salary>75000.0</salary>
  <designation>Manager</designation>
  <emailId>abc@test.com</emailId>
  <gender>female</gender>
  <maritalStatus>married</maritalStatus>
</Employees>

Here, In this new structure, we have introduced a nested name element as well as contactdetails element which is further nested to emergencyDetails elements. With our current code, we cannot extract or create the new nested section. So, along with creating a POJO class for Employees, will create a POJO class for name, contactDetails, and emergencyDetails.

Employees

public class Employees {

	Name name;
	ContactDetails contactdetails;

	private int age;
	private double salary;
	private String designation;
	private String emailId;
	private String gender;
	private String maritalStatus;

	// Getter and setter methods
	public Name getName() {
		return name;
	}

	public void setName(Name name) {
		this.name = name;
	}

	public ContactDetails getContactdetails() {
		return contactdetails;
	}

	public void setContactdetails(ContactDetails contactdetails) {
		this.contactdetails = contactdetails;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}

	public String getDesignation() {
		return designation;
	}

	public void setDesignation(String designation) {
		this.designation = designation;
	}

	public String getEmailId() {
		return emailId;
	}

	public void setEmailId(String emailId) {
		this.emailId = emailId;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public String getMaritalStatus() {
		return maritalStatus;
	}

	public void setMaritalStatus(String maritalStatus) {
		this.maritalStatus = maritalStatus;
	}

}

Name

public class Name {

	private String firtsname;
	private String middlename;
	private String lastname;

	public String getFirtsname() {
		return firtsname;
	}

	public void setFirtsname(String firtsname) {
		this.firtsname = firtsname;
	}

	public String getMiddlename() {
		return middlename;
	}

	public void setMiddlename(String middlename) {
		this.middlename = middlename;
	}

	public String getLastname() {
		return lastname;
	}

	public void setLastname(String lastname) {
		this.lastname = lastname;
	}

}

ContactDetails -As you can see that EmergencyDetails element which contains emergency_no1, emergency_no2, and emergency_no3 are nested within ContactDetails, so we have created a separate POJO class for EmergencyDetails.

public class ContactDetails {

	private String deskNumber;
	private String mobileNumber;

	EmergencyDetails emergencyDetails;

	public EmergencyDetails getEmergencyDetails() {
		return emergencyDetails;
	}

	public void setEmergencyDetails(EmergencyDetails emergencyDetails) {
		this.emergencyDetails = emergencyDetails;
	}

	public String getDeskNumber() {
		return deskNumber;
	}

	public void setDeskNumber(String deskNumber) {
		this.deskNumber = deskNumber;
	}

	public String getMobileNumber() {
		return mobileNumber;
	}

	public void setMobileNumber(String mobileNumber) {
		this.mobileNumber = mobileNumber;
	}

}

EmergencyDetails

public class EmergencyDetails {

	private String emergency_no1;
	private String emergency_no2;
	private String emergency_no3;

	public String getEmergency_no1() {
		return emergency_no1;
	}

	public void setEmergency_no1(String emergency_no1) {
		this.emergency_no1 = emergency_no1;
	}

	public String getEmergency_no2() {
		return emergency_no2;
	}

	public void setEmergency_no2(String emergency_no2) {
		this.emergency_no2 = emergency_no2;
	}

	public String getEmergency_no3() {
		return emergency_no3;
	}

	public void setEmergency_no3(String emergency_no3) {
		this.emergency_no3 = emergency_no3;
	}

}

Next, we create our serializeToXML() method:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.exc.StreamWriteException;
import com.fasterxml.jackson.databind.DatabindException;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.junit.Test;
import java.io.File;
import java.io.IOException;

public class ComplexEmployeeXMLTest {
    @Test
    public void serializationXML() {

        Employees employee = new Employees();

        Name empname = new Name();
        empname.setFirtsname("John");
        empname.setMiddlename("Dave");
        empname.setLastname("William");

        employee.setName(empname);
        employee.setAge(35);
        employee.setSalary(1355000);
        employee.setDesignation("Manager");

        ContactDetails contdetails = new ContactDetails();
        contdetails.setDeskNumber("00-428507");
        contdetails.setMobileNumber("+917823561231");

        EmergencyDetails emergency = new EmergencyDetails();
        emergency.setEmergency_no1("+91 1212898920");
        emergency.setEmergency_no2("+91 9997722123");
        emergency.setEmergency_no3("+91 8023881245");
        contdetails.setEmergencyDetails(emergency);

        employee.setContactdetails(contdetails);

        employee.setEmailId("abc@test.com");
        employee.setMaritalStatus("married");
        employee.setGender("female");

        XmlMapper xmlMapper = new XmlMapper();

        try {
            String employeeXml = xmlMapper.writerWithDefaultPrettyPrinter().writeValueAsString(employee);
            System.out.println(employeeXml);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        //To save the XML in a file and place under the project
        String userDir = System.getProperty("user.dir");
        try {
            xmlMapper.writerWithDefaultPrettyPrinter()
                    .writeValue(new File(userDir + "\\src\\test\\resources\\NestedXMLExample.xml"), employee);
        } catch (StreamWriteException e) {
            e.printStackTrace();
        } catch (DatabindException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

The output of the above program is

The file is saved under src/test/resources as NestedXMLExample.

There is another way to do the same job of converting Java Object to a complex XML, but which looks more sophisticated and less a number of lines of code.

I’ll use the same complex XML structure.

In this method, we will create a default constructor as well as a parametrized Constructor to pass the arguments for each POJO Class.

Employees

public class Employees {

	Name name;
	ContactDetails contactdetails;

	private int age;
	private double salary;
	private String designation;
	private String emailId;
	private String gender;
	private String maritalStatus;

	public Employees() {
		super();
	}

	public Employees(Name name, ContactDetails contactdetails, int age, double salary, String designation,
			String emailId, String gender, String maritalStatus) {

		this.name = name;
		this.contactdetails = contactdetails;
		this.age = age;
		this.salary = salary;
		this.designation = designation;
		this.emailId = emailId;
		this.gender = gender;
		this.maritalStatus = maritalStatus;
	}

	// Getter and setter methods
	public Name getName() {
		return name;
	}

	public void setName(Name name) {
		this.name = name;
	}

	public ContactDetails getContactdetails() {
		return contactdetails;
	}

	public void setContactdetails(ContactDetails contactdetails) {
		this.contactdetails = contactdetails;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}

	public String getDesignation() {
		return designation;
	}

	public void setDesignation(String designation) {
		this.designation = designation;
	}

	public String getEmailId() {
		return emailId;
	}

	public void setEmailId(String emailId) {
		this.emailId = emailId;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public String getMaritalStatus() {
		return maritalStatus;
	}

	public void setMaritalStatus(String maritalStatus) {
		this.maritalStatus = maritalStatus;
	}

}

Name

public class Name {

	private String firtsname;
	private String middlename;
	private String lastname;

	public Name() {
		super();
	}

	public Name(String firtsname, String middlename, String lastname) {
		super();
		this.firtsname = firtsname;
		this.middlename = middlename;
		this.lastname = lastname;
	}

	public String getFirtsname() {
		return firtsname;
	}

	public void setFirtsname(String firtsname) {
		this.firtsname = firtsname;
	}

	public String getMiddlename() {
		return middlename;
	}

	public void setMiddlename(String middlename) {
		this.middlename = middlename;
	}

	public String getLastname() {
		return lastname;
	}

	public void setLastname(String lastname) {
		this.lastname = lastname;
	}
}

ContactDetails

public class ContactDetails {

	private String deskNumber;
	private String mobileNumber;
	EmergencyDetails emergencyDetails;

	public ContactDetails() {
		super();
	}

	public ContactDetails(String deskNumber, String mobileNumber, EmergencyDetails emergencyDetails) {
		super();
		this.deskNumber = deskNumber;
		this.mobileNumber = mobileNumber;
		this.emergencyDetails = emergencyDetails;
	}

	public EmergencyDetails getEmergencyDetails() {
		return emergencyDetails;
	}

	public void setEmergencyDetails(EmergencyDetails emergencyDetails) {
		this.emergencyDetails = emergencyDetails;
	}

	public String getDeskNumber() {
		return deskNumber;
	}

	public void setDeskNumber(String deskNumber) {
		this.deskNumber = deskNumber;
	}

	public String getMobileNumber() {
		return mobileNumber;
	}

	public void setMobileNumber(String mobileNumber) {
		this.mobileNumber = mobileNumber;
	}
}

EmergencyDetails

public class EmergencyDetails {

	private String emergency_no1;
	private String emergency_no2;
	private String emergency_no3;

	public EmergencyDetails() {
		super();
	}

	public EmergencyDetails(String emergency_no1, String emergency_no2, String emergency_no3) {
		super();
		this.emergency_no1 = emergency_no1;
		this.emergency_no2 = emergency_no2;
		this.emergency_no3 = emergency_no3;
	}

	public String getEmergency_no1() {
		return emergency_no1;
	}

	public void setEmergency_no1(String emergency_no1) {
		this.emergency_no1 = emergency_no1;
	}

	public String getEmergency_no2() {
		return emergency_no2;
	}

	public void setEmergency_no2(String emergency_no2) {
		this.emergency_no2 = emergency_no2;
	}

	public String getEmergency_no3() {
		return emergency_no3;
	}

	public void setEmergency_no3(String emergency_no3) {
		this.emergency_no3 = emergency_no3;
	}
}

Now, let us create a Serialization Test.

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.junit.Test;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class XmlSerializationDemo2 {
    @Test
    public void serializationTest() {

        try {

            EmergencyDetails emergency = new EmergencyDetails("+91 894132345", "+91 8888221102", "+91 7223156288");
            ContactDetails contdetails = new ContactDetails("00-428507", "+917823561231", emergency);
            Name empname = new Name("Trina", "Sophia", "William");

            // Converting a Java class object to a XML
            XmlMapper xmlMapper = new XmlMapper();

            String xmlString = xmlMapper.writerWithDefaultPrettyPrinter().writeValueAsString(new Employees(empname,
                    contdetails, 35, 1450000.00, "Director", "trina@test.com", "female", "married"));
            System.out.println(xmlString);

            // write XML string to file
            String userDir = System.getProperty("user.dir");
            File xmlOutput = new File(userDir + "\\src\\test\\resources\\XMLExample.xml");
            FileWriter fileWriter = new FileWriter(xmlOutput);
            fileWriter.write(xmlString);
            fileWriter.close();

        } catch (JsonProcessingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

The output of the above program is

The newly created XML file is saved under src/test/resources as shown in the below image.

We have successfully serialized our Java object into XML and written it into an XML file.

In our serializationTest() function, we create an XmlMapper object, which is a child class to the ObjectMapper class used in JSON serialization. This class converts our Java Object into an XML output that we can now write to a file.

Hope it is useful. Happy Learning !!

How to pretty print JSON using the Gson library?

HOME

Add the below dependency to POM.xml to use Gson API.

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.10.1</version>
</dependency>

Let us take an example of a JSON.

{
  "firstName" : "Vibha",
  "lastName" : "Singh",
  "age" : 30,
  "salary" : 75000.0,
  "designation" : "Manager",
  "contactNumber" : "+919999988822",
  "emailId" : "abc@test.com"
  }

Let us create a table named Employee which contains the data members same as node names in the above JSON payload and their corresponding getter and setter methods.

public class Employee {

	// private data members of POJO class
	private String firstName;
	private String lastName;
	private int age;
	private double salary;
	private String designation;
	private String contactNumber;
	private String emailId;

	// Getter and setter methods
	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}

	public String getDesignation() {
		return designation;
	}

	public void setDesignation(String designation) {
		this.designation = designation;
	}

	public String getContactNumber() {
		return contactNumber;
	}

	public void setContactNumber(String contactNumber) {
		this.contactNumber = contactNumber;
	}

	public String getEmailId() {
		return emailId;
	}

	public void setEmailId(String emailId) {
		this.emailId = emailId;
	}

}

We will convert a Java Object to a JSON object as a String and also will write it into a .json file. There are many variations for the method toJson().

You can create a Gson instance by invoking a new Gson() if the default configuration is all you need, as shown in the below example.

  @Test
    public void withoutPretty() {

        // Create an object of POJO class
        Employee employee = new Employee();
        employee.setFirstName("Vibha");
        employee.setLastName("Singh");
        employee.setAge(30);
        employee.setSalary(75000);
        employee.setDesignation("Manager");
        employee.setContactNumber("+919999988822");
        employee.setEmailId("abc@test.com");

        Gson gson = new Gson();
        String employeeJsonPayload = gson.toJson(employee);
        System.out.println("Json :" + employeeJsonPayload);

    }

The execution message is shown below.

public GsonBuilder setPrettyPrinting()

@Test
    public void withPretty() {
        // Create an object of POJO class
        Employee employee = new Employee();
        employee.setFirstName("Vibha");
        employee.setLastName("Singh");
        employee.setAge(30);
        employee.setSalary(75000);
        employee.setDesignation("Manager");
        employee.setContactNumber("+919999988822");
        employee.setEmailId("abc@test.com");

        Gson gson = new GsonBuilder().setPrettyPrinting().create();

        String json = gson.toJson(employee);

        System.out.println("Pretty Json :" + json);

    }

Exclude Fields from Serialization in Gson – @Expose Annotation

HOME

The previous tutorials have explained the conversion of Java Object to JSON using Gson API. This tutorial explains the process of excluding the attributes from the JSON using Gson API.

@Expose helps control what class attributes can be serialized or deserialized.

@Expose(serialize = false)
private String lastName;

@Expose (serialize = false, deserialize = false)
private String emailAddress

Add the below dependency to POM.xml to use Gson API.

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.10.1</version>
</dependency>

Let us take an example of a JSON.

{
  "firstName": "Vibha",
  "lastName": "Singh",
  "salary": {
    "2018": 14000,
    "2012": 12000,
    "2010": 10000
  },
  "designation": "Manager",
  "emailId": [
    "abc@test.com",
    "vibha@test.com"
  ]
}

Let us create a table named Employee which contains the data members same as node names in the above JSON payload with @Expose annotation and their corresponding getter and setter methods.

package com.example.gson;

import com.google.gson.annotations.Expose;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

public class Employee {

    // private data members of POJO class

    @Expose(serialize = true)
    private String firstName;

    @Expose(serialize = true)
    private String lastName;

    @Expose(serialize = false)
    private int age;

    @Expose(serialize = true)
    private Map<String, BigDecimal> salary;

    @Expose()
    private String designation;

    @Expose(serialize = false)
    private String contactNumber;

    @Expose(serialize = true)
    private List<String> emailId;

    // Getter and setter methods
    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Map<String, BigDecimal> getSalary() {
        return salary;
    }

    public void setSalary(Map<String, BigDecimal> salary) {
        this.salary = salary;
    }

    public String getDesignation() {
        return designation;
    }

    public void setDesignation(String designation) {
        this.designation = designation;
    }

    public String getContactNumber() {
        return contactNumber;
    }

    public void setContactNumber(String contactNumber) {
        this.contactNumber = contactNumber;
    }

    public List<String> getEmailId() {
        return emailId;
    }

    public void setEmailId(List<String> emailId) {
        this.emailId = emailId;
    }

    @Override
    public String toString() {
        return "(firstName: " + firstName + "," +
                "lastName: " + lastName + "," +
                "age: " + age + ", " +
                "salary: " + salary + "," +
                "designation: " + designation + ", " +
                "contactNumber: " + contactNumber + ", " +
                "emailId: " + emailId + ")";

    }
}

Suppose the attribute age and contactNumber in the Employee class should not serialize because it’s sensitive information. Hence, we must decorate these attributes with the annotation @Expose(serialize=false):

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.junit.Test;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class GsonExpose_Demo {

    @Test
    public void gsonExposeTest()  {

        // Create an object of POJO class
        Employee employee = new Employee();
        employee.setFirstName("Vibha");
        employee.setLastName("Singh");
        employee.setAge(30);
        Map<String, BigDecimal> salary = new HashMap() {{
            put("2010", new BigDecimal(10000));
            put("2012", new BigDecimal(12000));
            put("2018", new BigDecimal(14000));
        }};

        employee.setSalary(salary);
        employee.setDesignation("Manager");
        employee.setContactNumber("+919999988822");
        employee.setEmailId(Arrays.asList("abc@test.com","vibha@test.com"));

        Gson gson = new GsonBuilder().setPrettyPrinting().excludeFieldsWithoutExposeAnnotation().create();
        String employeeJsonPayload = gson.toJson(employee);
        System.out.println("Json :" + employeeJsonPayload);

    }
}

The output of the above program is shown below.

How to read JSON from File Using Gson API

HOME

The previous tutorials have explained the conversion of Java Object to JSON using Gson API. This tutorial explains the process of reading the JSON Payload from a file using Gson API.

Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object. Gson can work with arbitrary Java objects, including pre-existing objects for those you do not have source code.

  • Provide simple toJson() and fromJson() methods to convert Java objects to JSON and vice versa.

Add the below dependency to POM.xml to use Gson API.

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.10.1</version>
</dependency>

Let us take an example of a JSON.

{
  "firstName": "Vibha",
  "lastName": "Singh",
  "age": 30,
  "salary": {
    "2023": 74000,
    "2022": 62000,
    "2021": 50000
  },
  "designation": "Manager",
  "contactNumber": "+919999988822",
  "emailId": "abc@test.com"
}

Let us create a table named Employee which contains the data members same as node names in the above JSON payload and their corresponding getter and setter methods.

import java.math.BigDecimal;
import java.util.Map;

public class Employee {

    // private data members of POJO class
    private String firstName;
    private String lastName;
    private int age;
    private Map<String, BigDecimal> salary;
    private String designation;
    private String contactNumber;
    private String emailId;

    // Getter and setter methods
    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Map<String, BigDecimal> getSalary() {
        return salary;
    }

    public void setSalary(Map<String, BigDecimal> salary) {
        this.salary = salary;
    }

    public String getDesignation() {
        return designation;
    }

    public void setDesignation(String designation) {
        this.designation = designation;
    }

    public String getContactNumber() {
        return contactNumber;
    }

    public void setContactNumber(String contactNumber) {
        this.contactNumber = contactNumber;
    }

    public String getEmailId() {
        return emailId;
    }

    public void setEmailId(String emailId) {
        this.emailId = emailId;
    }

    @Override
    public String toString() {
        return "(firstName: " + firstName + "," +
                "lastName: " + lastName + "," +
                "age: " + age + ", " +
                "salary: " + salary + "," +
                "designation: " + designation + ", " +
                "contactNumber: " + contactNumber + ", " +
                "emailId: " + emailId + ")";

    }
}

We will convert a JSON Object to a Java Object.

You can create a Gson instance by invoking a new Gson() if the default configuration is all you need, as shown in the below example.

import org.junit.Test;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;

public class GsonReadFromFile {

    @Test
    public void readJsonFromFile() throws FileNotFoundException {

        String userDir = System.getProperty("user.dir");
        File jsonFilePath = new File(userDir + "\\src\\test\\resources\\Employee.json");
        FileReader fileReader = new FileReader(jsonFilePath);

        Gson gson = new Gson();
        Employee employee = gson.fromJson(fileReader, Employee.class);
        System.out.println(employee.toString());

        System.out.println("FirstName :" + employee.getFirstName());
        System.out.println("LastName :" + employee.getLastName());
        System.out.println("Age :" + employee.getAge());
        System.out.println("Salary :" + employee.getSalary());
        System.out.println("Designation :" + employee.getDesignation());
        System.out.println("ContactNumber :" + employee.getContactNumber());
        System.out.println("EmailId :" + employee.getEmailId());


    }
}

The execution message is shown below.

How to save Json in File Using Gson API

HOME

The previous tutorials have explained the conversion of Java Object to JSON using Gson API. This tutorial explains the process of saving JSON Payload in a file using Gson API.

Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object. Gson can work with arbitrary Java objects, including pre-existing objects those you do not have source code.

  • Provide simple toJson() and fromJson() methods to convert Java objects to JSON and vice versa.
  • Allow pre-existing unmodifiable objects to be converted to and from JSON.
  • Extensive support of Java Generics.
  • Allow custom representations for objects.
  • Support arbitrarily complex objects (with deep inheritance hierarchies and extensive use of generic types).

Add the below dependency to POM.xml to use Gson API.

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.10.1</version>
</dependency>

Let us take an example of a JSON.

{
  "firstName" : "Vibha",
  "lastName" : "Singh",
  "age" : 30,
  "salary" : 75000.0,
  "designation" : "Manager",
  "contactNumber" : "+919999988822",
  "emailId" : "abc@test.com"
  }

Let us create a table named Employee which contains the data members same as node names in the above JSON payload and their corresponding getter and setter methods.

public class Employee {

	// private data members of POJO class
	private String firstName;
	private String lastName;
	private int age;
	private double salary;
	private String designation;
	private String contactNumber;
	private String emailId;

	// Getter and setter methods
	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}

	public String getDesignation() {
		return designation;
	}

	public void setDesignation(String designation) {
		this.designation = designation;
	}

	public String getContactNumber() {
		return contactNumber;
	}

	public void setContactNumber(String contactNumber) {
		this.contactNumber = contactNumber;
	}

	public String getEmailId() {
		return emailId;
	}

	public void setEmailId(String emailId) {
		this.emailId = emailId;
	}

}

We will convert a Java Object to a JSON object as a String and also will write it into a .json file. There are many variations for the method toJson().

You can create a Gson instance by invoking a new Gson() if the default configuration is all you need, as shown in the below example.

You can also use GsonBuilder to build a Gson instance with various configuration options such as versioning support, pretty-printing, custom JsonSerializer, JsonDeserializer.

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.junit.Test;
import java.io.File;
import java.io.FileWriter;

public class WriteJsonFileDemo {

    @Test
    public void saveJsonToFile() {

        Employee employee = new Employee();
        employee.setFirstName("Vibha");
        employee.setLastName("Singh");
        employee.setAge(30);
        employee.setSalary(75000);
        employee.setDesignation("Manager");
        employee.setContactNumber("+919999988822");
        employee.setEmailId("abc@test.com");

        Gson builder = new GsonBuilder().setPrettyPrinting().create();
        String employeePrettyJsonPayload = builder.toJson(employee);
        System.out.println(employeePrettyJsonPayload);

        String userDir = System.getProperty("user.dir");
        File outputJsonFile = new File(userDir + "\\src\\test\\resources\\testData\\EmployeePayloadUsingGson.json");
        try {
            FileWriter fileWriter = new FileWriter(outputJsonFile);
            builder.toJson(employee, fileWriter);
            fileWriter.flush();
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

The execution message is shown below.