AndyB
AndyB

Reputation: 513

Parsing a request body containing a quoted string as JSON in Spring Boot 2

I have an application which exposes an endpoint accepting PUT requests as a JSON-formatted string, e.g.:

PUT /my/endpoint
"some string"

My endpoint method signature is something like:

@RequestMapping(
        path = "/my/endpoint",
        consumes = "application/vnd.mycompany.myservice-v1.hal+json"
)
public ResponseEntity<MyResponse> myEndpoint(
        @RequestBody final String myString
) {
    ...
}

Using Spring Boot 1 (1.5.22.RELEASE), the value of myString given the PUT example above would be the literal text some string, but under Spring Boot 2 (2.3.6.RELEASE), it's now the literal text "some string" - i.e. it seems that the input isn't strictly being parsed as JSON because the quotes are not removed.

I believe that quoted strings are valid JSON (and that unquoted strings are not), just as an object (in { and }) and a list (in [ and ]) would be.

I've taken out some extraneous detail that I don't think matters for the problem at hand (e.g. we're using CompletableFuture as a return value, I've got a @PathVariable in there as well and there's some annotation-driven validation going on), but I've left in that we're using a custom media-type in case that has something to do with it.

Any ideas how I can convince Spring Boot 2 to treat my request body as JSON properly? Unfortunately, I can't redefine the API because we already have live customers using it.

Upvotes: 14

Views: 9535

Answers (2)

Banyenzachi
Banyenzachi

Reputation: 11

You Can create the request object

public class MyObject{
private String myStr;

}

Use the MyObject class as RequestBody object with mediaType="application/json"

In your controller

@RequestMapping(
        value= "/my/endpoint", method= RequestMethod.PUT
)
public ResponseEntity<MyResponse> myEndpoint(
        @RequestBody final MyObject myObj
) 

Upvotes: 0

pirho
pirho

Reputation: 12215

This might not be the best option but if nothing else helps at start. Instead of String let Spring handle RequestBody as an Object. So like:

public ResponseEntity<String> myEndpoint(@RequestBody final Object myString)

When using String Spring might not even use Jackson for parsing but handle the body as a String that should have all the characters in the body even content type is set to JSON.

If you do the following:

String myString2 = new ObjectMapper().readValue(myString, String.class);

you can see it resulting into myString2 having not those surrounding double quotes.

For Object Spring seems to handle it differently. It makes it to a String but seems to consider it as a JSON value (and as a String value because having surrounding double quotes) it should not have surrounding double quotes.

If you use Object and then log myString.getClass() you will see it is actually a java.lang.String

Upvotes: 8

Related Questions