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.

Answer

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



Source: stackoverflow