Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accept arbitrary JSON as RequestBody in Spring

As the title suggests, I'd like my controller class to accept (mostly) arbitrary JSON in the RequestBody as part of a POST. Before you ask why I'd want unworkable JSON, it's because the JSON is simply passing through to a storage backend with very minimal processing (only extracting one field).

There are three required fields in this JSON: data, schema, and resourceID. Here's what my request class looks like:

public class MyRequestBody implements Serializable {

    private JsonObject data;
    private JsonObject schema;
    private String resourceID;
    ...

I already understand the serialization issues that cause this not to work. The reason I don't want to expand this data model further to define fields for data and schema is that I simply do not know how nested they will be. That is also why I don't simply use Map<String, String>.

Is there a simple solution to receiving arbitrary, nested JSON data as part of the RequestBody, or am I forced to either write a large, strongly typed data model or accept it as an Object, convert to JSON, and do all my field validation somewhere else?

Controller signature for reference:

@RequestMapping(value = "test/data", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public ResponseEntity<StorageData> publishData(@RequestBody MyRequest requestBody) {

Here's some example JSON. Where things get dicey are in the data and schema section where they may contain multiple levels of nesting that I wouldn't be aware of:

{
    "data": {
        "display": "bilbo_baggins"
    },
    "resourceID": "0123456789",
    "schema": {
        "type": "record",
        "namespace": "com.org.test",
        "name": "mySchema",
        "fields": [{
            "name": "display",
            "type": "string"
        }]
    }
}
like image 855
J_Stan Avatar asked Jul 16 '18 17:07

J_Stan


People also ask

How do I accept JSON in request body?

Set the Request Content-Type Header Parameter. Set the “content-type” request header to “application/json” to send the request content in JSON form. This parameter has to be set to send the request body in JSON format.

How do you do a RequestBody in Spring boot?

In this article, we will discuss how to get the body of the incoming request in the spring boot. @RequestBody: Annotation is used to get request body in the incoming request. Note: First we need to establish the spring application in our project. Step 2: Click on Generate which will download the starter project.

What is the use of @RequestBody annotation in Spring?

Simply put, the @RequestBody annotation maps the HttpRequest body to a transfer or domain object, enabling automatic deserialization of the inbound HttpRequest body onto a Java object. Spring automatically deserializes the JSON into a Java type, assuming an appropriate one is specified.

Can we use @RequestBody in Spring MVC?

The @RequestBody annotation is applicable to handler methods of Spring controllers. This annotation indicates that Spring should deserialize a request body into an object. This object is passed as a handler method parameter.


1 Answers

  1. You can receive a JsonNode object for an arbitrary JSON

Like this:

@RequestMapping(value = "test/data", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public ResponseEntity<StorageData> publishData(@RequestBody JsonNode requestBody) {.. }
  1. Change MyRequestBody class to use JsonNode instead of JsonObject for data and schema. You don't need to implement Serializable, unless you need it for something else in your code, but it's not needed for receiving Json objects in request.
like image 182
D. Mayen Avatar answered Oct 30 '22 21:10

D. Mayen