I have the following code in my Spring Boot app:
@RestController
@RequestMapping("/execute")
public class RestCommandExecutor {
@PostMapping
public Response executeCommand(@RequestBody Command command,
HttpEntity<String> httpEntity) {
System.out.println(command);
System.out.println("********* payload is: " + httpEntity.getBody());
return new Response("Hello text", new Long(123));
}
}
When a POST request comes in with the proper Command
, I get an I/O error:
.w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: I/O error while reading input message; nested exception is java.io.IOException: Stream closed
I'd like Spring to translate the request body into Command
, but since the JSON holds more than what is part of the Command
class, I'd like to get the full JSON in raw as well.
Is there a way to achieve this through mapping in the method? I know I can always do this public Response executeCommand(HttpEntity<String> httpEntity)
and then manually translate it into Command
using Jackson, but I would rather not have to do that manually.
Is that possible?
The reason you can’t both read the HttpEntity
’s body and use @RequestBody
is that both read from the HttpRequest
’s InputStream
and close it afterwards. Since you can’t read again from the InputStream
after it’s closed, the last operation fails as you see.
It seems what you actually want is to access some properties that aren’t mapped in the Command
class, particularly into a class specified using a type
property.
You can do this using Jackson’s @JsonTypeInfo
and @JsonSubtype
annotations, which allow you customize the deserialization for a class hierarchy.