How use Jakarta JSON binding to serialize Java objects

Test Environment
- OpenJDK 17.0.13
- Eclipse GlassFish 7.0.20
- Apache Maven 3.9.1
- VSCode Editor 1.97.2
What is Jakarta JSON Binding
JSON is one of the most popular data exchange format widely used to communicate between different webservices and connected applications. Jakarta JSON-B is a standard binding layer for converting Java objects to/from JSON messages. It defines a default mapping algorithm for converting existing Java classes to JSON, while enabling developers to customize the mapping process through the use of Java annotations.
One Jakarta JSON Binding reference implementation is Yasson, which is developed through Eclipse.org and is included as part of GlassFish Server. The Jakarta JSON Binding specification provides a standard binding layer (metadata and runtime) between Java classes and JSON documents.
Procedure
Step1: Create a maven quickstart project
Here in this step we will first create a maven quickstart project with the following options as shown below.
admin@fedser:vscodeprojects$ mvn archetype:generate -DgroupId=com.stack -DartifactId=jsonbindtest -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.5 -DinteractiveMode=false
admin@fedser:vscodeprojects$ cd jsonbindtest/
Step2: Update pom.xml with JSON-B dependencies
In order to use Jakarta JSON binding API and its implementation, we need to include the “jakarta.json.bind-api” and “yasson” dependencies as shown below. Jakarta JSON Binding is a standard binding layer for converting Java objects to/from JSON documents. Eclipse Yasson is the Reference implementation of JSR-367 (JSON-B).
Also we need to update our plugins to incldue “maven-shade-plugin”. This plugin provides the capability to package the artifact in an uber-jar, including its dependencies and to shade – i.e. rename – the packages of some of the dependencies. We can create a single independent jar file containing everything necessary to run the project.
An uber-JAR, also known as a fat JAR or JAR with dependencies, is a JAR file that contains not only a Java program but embeds its dependencies as well, and might also contain the web application that needs to be executed.
admin@fedser:jsonbindtest$ cat pom.xml
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.stack</groupId>
<artifactId>jsonbindtest</artifactId>
<version>1.0-SNAPSHOT</version>
<name>jsonbindtest</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>17</maven.compiler.release>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.11.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<!-- Optionally: parameterized tests support -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jakarta.json.bind</groupId>
<artifactId>jakarta.json.bind-api</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>yasson</artifactId>
<version>3.0.4</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.4.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.3.1</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.3.0</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>3.1.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>3.1.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.12.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.6.1</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.stack.App</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Step3: Create a Model Java Object
Now, let us create a very basic java class to model the person object. This class contains two instance variables named “name” and “address”. Also let’s add the getter and setter methods along with the construtors as shown below. We need default constructor when we need to deserialize the json output to an java object.
admin@fedser:jsonbindtest$ cat src/main/java/com/stack/Person.java
package com.stack;
public class Person {
private String name;
private String address;
public Person() {
}
public Person(String name, String address) {
this.name = name;
this.address = address;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAddress(String address) {
this.address = address;
}
public String getAddress() {
return address;
}
@Override
public String toString() {
return "Person {" +
"name: '" + name + '\'' +
", address: '" + address + '\'' +
'}';
}
}
Step4: Update App.java to serialize and deserialzie java object
Here is our App.java class wherein we first instantiate an object of class type person. This is the object that we will serialize to JSON document and deserialize later.
A jsonb instance provides access to methods for binding objects to JSON (ie. serializing Java object to JSON document).
Jakarta JSON Binding supports many ways to customize the default mapping behavior. First we are creating JsonbConfig object that sets the FORMATTING property to specify whether or not the serialized JSON data is formatted with linefeeds and indentation. Here we are setting this to true.
JsonbBuilder class provides the client’s entry point to the JSON Binding API. It builds Jsonb instances based on all parameters and configuration provided before calling build() method. For most use-cases, only one instance of JsonbBuilder is required within the application.
Jsonb provides an abstraction over the JSON Binding framework operations.
- fromJson: read JSON input, deserialize to Java objects content tree
- toJson: serialize Java objects content tree to JSON input
admin@fedser:jsonbindtest$ cat src/main/java/com/stack/App.java
package com.stack;
import jakarta.json.bind.Jsonb;
import jakarta.json.bind.JsonbBuilder;
import jakarta.json.bind.JsonbConfig;
public class App {
public static void main(String[] args) {
String jsonoutput;
Person person = new Person("Alice", "Wonder Land");
// Create a JSON-B object with custom configuration
JsonbConfig config = new JsonbConfig().withFormatting(true);
Jsonb jsonb = JsonbBuilder.create(config);
// Serailize Java object to JSON document
jsonoutput = jsonb.toJson(person);
System.out.println(jsonoutput);
// Deserialize JSON document to Java object
String aliceJson = "{ \"address\": \"Wonder Land\", \"name\": \"Alice\" }";
Person alice = jsonb.fromJson(aliceJson, Person.class);
System.out.println(alice.toString());
}
}
Step5: Build and Package Application
Here we are going clean the workspace and build and compile jar package as shown below.
admin@fedser:jsonbindtest$ mvn clean package
Step6: Validate Application
Now, its time to validate our standalone jar application to verify how its serializes our person object to JSON document as shown below.
admin@fedser:jsonbindtest$ java -jar target/jsonbindtest-1.0-SNAPSHOT.jar
{
"address": "Wonder Land",
"name": "Alice"
}
Person {name: 'Alice', address: 'Wonder Land'}
Hope you enjoyed reading this article. Thank you..
Leave a Reply
You must be logged in to post a comment.