How to Read JSON Data with Spring WebClient

A guide to Reading JSON Data with Spring WebClient and mapping JSON Objects to POJOs and Objects using WebFlux Mono and Flux.

Overview

Spring WebClient is a reactive and non-blocking client for making HTTP requests. Spring released WebClient as part of the Spring WebFlux framework. This tutorial guides us to use WebClient to access another service and consume its data in JSON form.

In today’s world, when we exchange data with other services, we use JSON as a preferred format. In this tutorial, first, we will use WebClient to read a single JSON object and parse it into a POJO. Later, we will study how to use WebClient to read a list of JSON objects and parse them into an array of POJO or an Array of generic Object instances.

JSON Objects

Let’s consider we have an Employee Service, which our WebClient will consume. The GET employee endpoint on the service returns a list of all employees in JSON format.

Service Endpoints
Next are the endpoints our WebClient will execute and consume the JSON data they return.

  • GET /employees
  • GET /employees/{id}

Sample JSON Data
The response of the service’s endpoint that returns an array of JSON objects will look like this.

[{
  "id":111,
  "name":"Jon",
  "department":{
    "id":222,
    "name":"Sales"
  }
},
{
  "id":112,
  "name":"Mac",
  "department":{
    "id":223,
    "name":"Engineering"
  }
}]Code language: JSON / JSON with Comments (json)

Setup

We need a minimal setup for this application. The first is to add the required Maven or Gradle dependency, and the other is to create model classes to parse the JSON data into.

Dependency

To use WebClient, we need to add a dependency on Spring WebFlux. In a Spring Boot project, we can add a starter dependency for WebFlux.

Maven Dependency (pom.xml)

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>Code language: HTML, XML (xml)

or Gradle Dependency (build.gradle)

implementation group: 'org.springframework.boot', name: 'spring-boot-starter-webflux'Code language: Gradle (gradle)

Model Classes

Next, we will create model classes into which we will transform the JSON objects. Looking at the sample JSON, we can figure out there are employee objects having department objects nested within.

Employee

public class Employee {
  private long id;
  private String name;
  private Department department;

  // Constructors, Getter, and Setter Methods
}Code language: Java (java)

Department

public class Department {
  private long id;
  private String name;

  // Constructors, Getter, and Setter Methods
}Code language: Java (java)

Read a JSON Object with WebClient

Mono is a reactive publisher that can emit 0 or 1 element. Thus, we should use Mono publisher to retrieve a single JSON resource with WebClient. We will use WebClient to read a JSON object and parse it into POJO.

Example of WebClient reading single JSON Object as a POJO with Mono.

Mono<Employee> employeeMono = WebClient
    .create(SERVICE_URL + "/employees/111")
    .get()
    .retrieve()
    .bodyToMono(Employee.class);Code language: Java (java)

Once we get the Mono of the Employee POJO object, we can then invoke block() on the Mono to get the Employee POJO instance.

Employee employee = employeeMono
    .share().block();Code language: Java (java)

Read JSON Object Array with WebClient

A JSON array of objects contains zero or N objects. Similarly, a Flux publisher emits zero or N elements making it a perfect fit for reading a JSON list or array. However, we can also read the complete JSON array as an array of POJO using Mono.

JSON Array as a Flux of POJO

To read a Flux of POJO object, we need to use the bodyToFlux() method.
Example of reading our JSON Object with WebClient as a Flux of Employee POJO

Flux<Employee> employeeFlux = WebClient
    .create(SERVICE_URL + "/employees")
    .get()
    .retrieve()
    .bodyToFlux(Employee.class);Code language: Java (java)

Then, we can use Java Stream Collector on the Flux to collect its elements in a List.

List<Employee> employees = employeeFlux
    .collect(Collectors.toList())
    .share().block();Code language: Java (java)

The collect() on the Flux returns a Mono of List. Thus we are executing block() to get a List of Employee objects.

JSON Array as a Mono of POJO Array

Now, let’s read the whole JSON Array using Spring Mono.
Example of reading our JSON Array using WebClient Mono to create an Array of Employee POJO.

Mono<Employee[]> employeesMono =  WebClient
    .create(SERVICE_URL + "/employees")
    .get()
    .retrieve()
    .bodyToMono(Employee[].class);Code language: Java (java)

We have used the bodyToMono() by providing an Employee Array class. That returns a Mono of Employee[].

Employee[] employees = employeesMono
    .share().block();Code language: Java (java)

Next, we can invoke the block() on the Mono to retrieve the Employee POJO Array.

JSON Array as a Mono of Generic Array

Alternatively, we generically read the JSON Array as a Mono of Java’s Object class.

Example of reading our JSON Array using WebClient to get Mono of Objects.

Mono<Object[]> objectsMono = WebClient
    .create(SERVICE_URL + "/employees")
    .get()
    .retrieve()
    .bodyToMono(Object[].class);Code language: Java (java)

Similarly, we can call block() on the Mono to get Object[].

Object[] objects = objectsMono
    .share().block();Code language: Java (java)

Summary

This quick tutorial covered examples of reading JSON Data with Spring 5 WebClient. On a high level, we created examples of reading a single resource JSON object and a JSON array of objects. First, we used WebClient to parse a JSON object into a Java Bean (POJO) using Mono. Next, we saw examples of using Mono or Flux with WebClient to read an array of JSON objects into an array of POJO or an array of generic Objects.