I'm using Spring Boot 2.5.6
and Spring WebFlux
. In my business case, I need to use the HTTP request body in two different forms:
- Raw JSON string
- Already parsed Java DTO
There are my RestContoller
:
@PostMapping("/play")
public Mono<PlayResponse> play(@RequestBody PlayCommand parsedBody,
@RequestBody String jsonBody) {
//code here
}
When I run tests I get the next exception:
java.lang.IllegalStateException: Only one connection receive subscriber allowed.
at reactor.netty.channel.FluxReceive.startReceiver(FluxReceive.java:182) ~[reactor-netty-core-1.0.12.jar:1.0.12]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
*__checkpoint ⇢ HTTP POST "/play" [ExceptionHandlingWebHandler]
When I use the next method signature:
@PostMapping("/play")
public Mono<PlayResponse> play(PlayCommand playCommand,
@RequestBody String body){
//code here
}
PlayCommand parsedBody
has all fields is set to 'null'.
I can't find a way to receive the body properly.
I understand, that I can use objectMapper
and convert playCommand
back to JSON, but this is additional work that does not need to be done.
Is it possible to receive the request body in two different forms? Or maybe, I'm doing something wrong in my examples?
CodePudding user response:
Having multiple @RequestBody
is not possible. If you really need both original JSON and its serialized version the best you can do is receive the request body as a plain String
and then convert it to the corresponding Java object as follows:
@Autowired
private ObjectMapper objectMapper;
@PostMapping("/play")
public Mono<PlayResponse> play(@RequestBody String body){
PlayCommand playCommand = objectMapper.readValue(body, PlayCommand.class);
}