SpringBoot WebFlux - Reading a request body with Spring WebFlux for Controller

less than 1 minute read

SpringBoot WebFlux 2.2.x requires to load the request body by using an input stream.
Below example will show how it can convert the json data into the expected class after loading json data with an input stream.

Full source code can be found from https://github.com/nsclass/ns-svg-converter/blob/master/ns-main-service/src/main/java/com/acrocontext/reactive/rest/SvgConverterController.java

Github: https://github.com/nsclass/ns-svg-converter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    private <T> T toRequestBody(InputStream inputStream, Class<T> classValue) {
        try {
            return objectMapper.readValue(inputStream, classValue);
        } catch(Exception e){
            throw new RuntimeException(e);
        }
    }
    public static class InputStreamCollector {
        private InputStream inputStream;
        public void collectInputStream(InputStream inputStream) {
            if (this.inputStream == null) {
                this.inputStream = inputStream;
            }
            this.inputStream = new SequenceInputStream(this.inputStream, inputStream);
        }
        public InputStream getInputStream() {
            return this.inputStream;
        }
    }

REST Controller

1
2
3
4
5
6
7
8
9
10
11
    @PutMapping(path = "/conversion",
            consumes = MediaType.APPLICATION_JSON_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public Mono<SvgConvertRespondView> convertImage(ServerWebExchange exchange) {
        return exchange.getRequest().getBody()
                .collect(InputStreamCollector::new, (inputStreamCollector, dataBuffer)->
                        inputStreamCollector.collectInputStream(dataBuffer.asInputStream()))
                .map(InputStreamCollector::getInputStream)
                .map(inputStream -> toRequestBody(inputStream, SvgConvertRequestView.class))
                .map(this::convertRespondView);
    }