JSON-B : An Introduction
Tags: java, javaee, jakartaee
Published: 2022-08-31 10:49:56

The **Java API for JSON Binding** ([JSON-B](https://jakarta.ee/specifications/jsonb/3.0/)) is a JavaEE/JakartaEE specification (**JSR-353**) to convert Java objects to json & vice-versa. [Apache Johnzon](http://johnzon.apache.org/) is an implementation of the JSON-B spec. 

[Javadoc](https://jakarta.ee/specifications/jsonb/3.0/apidocs)  

JSON-B is an alternative to GSON & Jackson.

Consider the following Java class (simplified)

```java
class Task {
    String description;
    LocalDate deadline;
    boolean over;
}
```

You can convert `Task` instances to json as follows:

```java
Task task = new Task("Jump")
Jsonb jsonb = JsonbBuilder.create();
String taskJson = jsonb.toJson(task);
```

`{"deadline":"2021-10-15","description":"Jump","over":false}`

Let's say I want to initialize a bunch of Task objects from [fakerestapi.azurewebsites.net](https://fakerestapi.azurewebsites.net/). It provides a json web-service for activities with the following schema :

[![Activity schema: id title dueDate completed](https://yuml.me/5ddf521e.jpg)](http://yuml.me/diagram/scruffy/class/,%20,%20%2F%2F%20Add%20more%20detail,%20%5BActivity%7C+id:%20Number;+title:%20String;+dueDate:%20Date;+completed:%20Boolean%5D.jpg)

To convert this json objects of this schema to `Activity` instances, you can use the `@JsonbProperty` annotation.

```java
class Task {
    @JsonbProperty("title")
    String description;

    @JsonbProperty("dueDate")
    LocalDate deadline;

    @JsonbDateFormat(JsonbDateFormat.DEFAULT_FORMAT)
    @JsonbProperty("completed")
    boolean over;

    @JsonbNillable
    // creator can be optionally present in json
    String creator; 
}
```

Properties that can be optionally present/absent in the json, must be annotated with `@JsonbNillable`

Suppose you have multiple sources of Activities each with their own schema you can create & use `JsonbAdapter`s.

```java
@JsonbTypeAdapter
class GermanTaskAdapter implements JsonbAdapter<Task, JsonObject> {

    public Task adaptFromJson(JsonObject jo) {
       var description = jo.getString("Titel");
       var deadline = LocalDate.parse(jo.getString("Stichtag"));
       var over = jo.getBoolean("vollendet");
       return new Task(description, deadline, over);
    }

    public JsonObject adaptToJson(Task task) {
       return Json.createObjectBuilder()
           .add("id", 0)
           .add("Titel", task.getTitle())
           .add("Stichtag", task.getDeadline().toString())
           .add("vollendet", task.isOver())
    }
}
```

You can have multiple adapters for a domain class, through which you can consume from multiple sources & provide multiple json implementations.

In the above adapter, I have used the **Java API for JSON Processing
**[**JSON-P API**](https://jakarta.ee/specifications/jsonp/2.1/) to create and use `JsonObject` instances.

If you are using Spring there is [`JsonbHttpMessageConverter`](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/converter/json/JsonbHttpMessageConverter.html) since version 5.


*This is my first online technical article (was unpublished for a looong time). Questions & Feedback welcome. 
Thanks for reading.*