Spring Rest:Jackson’s JsonNode for Payload unaware request Handling

Generally, while creating a Rest application using Spring one would leverage Jackson’s message converter to convert the received JSON onto domain object in java i.e typically a POJO.

Example: Let’s say there is a request which we need to send to the service then that has to be de-serialized to a Java object.Java object would be this:

package com.example.demo;public class Request {
private String firstName;
private String lastName;
private int age;

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;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(“Request [firstName=”);
builder.append(firstName);
builder.append(“, lastName=”);
builder.append(lastName);
builder.append(“, age=”);
builder.append(age);
builder.append(“]”);
return builder.toString();
}
}

And this has to be received at the Spring Controller method with annotation @RequestBody like this:

package com.example.demo.controller;import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.Request;
@RestController
public class HomeController {

@RequestMapping("/submitRequest")
public String processRequest(@RequestBody Request request) {
System.out.println("Request:"+request);
return "Response of processed request!";
}
}

But,there would be few cases where the rest service will just be used as a proxy i.e when the Rest service is used to forward the request on to another 3rd party service or to a service present in another application and to receive the response payload back to the requester.In this scenario,we may not require to know the request and response Payload structure i.e the structure of the JSON to map it onto domain model object.So,how would we deal with this situation?

One solution for this is Spring netflix zuul proxy which can be used to just forward the request and send the response received from the 3rd party service back to the requester.But,it requires the application to be a Spring Boot application.It just does not work with Spring MVC.

The other solution and that which works For application which is not a Spring boot application is,we can just use JSONNode object present in Jackson module, to de-serialize the request JSON even if we are unaware or does not need to know of the request and response payload structure.

Example:

package com.example.demo.controller;import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.databind.JsonNode;@RestController
public class DemoController {

@RequestMapping(value="/ping",method = RequestMethod.POST)
public JsonNode index(@RequestBody JsonNode jsonNode) {
System.out.println("Received JSON:"+jsonNode.toString());
return jsonNode;
}
}

Let’s test this by sending a sample request from a REST client:

Image for post
Image for post
I have sent the JSON by hitting the service that uses JSONNode for deserializing RequestBody

Let us have a look at what we received at the controller:

Image for post
Image for post

We just received the JSON object without having to know the request payload structure and without having to use the Java domain object.

We can also modify the payload structure at the REST client without having to make any modifications at Spring Controller.Let’s test this by sending a request with different payload structure and still the request will be processed at Spring Controller.

Image for post
Image for post
New Request with a different Payload structure

Request received at controller:

Image for post
Image for post
We can see the request payload structure is changed,still the request is received and processed at Controller

As you can see the benefit of JSONNode is that the request payload can be changed and still can be processed at Controller.

The real benefit of using JsonNode comes when the rest service controller is just used as a proxy i.e when the rest service is used to just forward the request to another rest service ,forward the response from another rest service back to the requester.Let’s see this with an example.

Let us assume we have another rest service which is consumed from the Controller.Example of this kind of rest service.

@RequestMapping(“/submitRequest”)
public Response processRequest(@RequestBody Request request) {
System.out.println(“Request:”+request);
Response response = new Response();
response.setResponseMessage(“Processed Successfully”);
response.setResponseStatus(“Success”);
return response;
}

And this service would be consumed from the controller we have.

@RequestMapping(value=”/ping”,method = RequestMethod.POST)
public JsonNode index(@RequestBody JsonNode jsonNode) {
//System.out.println(“Received JSON:”+jsonNode.toString());

RestTemplate restTemplate = new RestTemplate();
HttpEntity<JsonNode> request = new HttpEntity<>(jsonNode);

String url = “http://localhost:8080/submitRequest”
ResponseEntity<JsonNode> response =
restTemplate.exchange(url,
HttpMethod.POST,
request,
JsonNode.class);
JsonNode responsePayload = response.getBody();
return responsePayload;
}

Let’s test this by sending the request from rest client:

Image for post
Image for post
We have hit the ‘ping’ service and it calls another service in the background

Written by

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store