MMR
MMR

Reputation: 65

WebFlux - read plain text request body in Webflux

I am using Java WebFlux version 2.5.2. I need to extract the plain text, which is coming as POST request and then I will have to process the text. How can I extract the body from ServerRequest object?.

I am pasting my router and handler code. Attaching the image with the watch window which shows the error for the code where I try to extract the payload.

enter image description here

Router class is as follows:

package com.test;

import com.test.AppHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;

import static org.springframework.web.reactive.function.server.RequestPredicates.*;

@Configuration
public class AppRouter {

    @Bean
    public RouterFunction<ServerResponse> route(AppHandler appHandler){
        return RouterFunctions
                .route(GET("/").and(accept(MediaType.TEXT_PLAIN)), appHandler::ping)
                .andRoute(POST("/process").and(accept(MediaType.ALL)).and(contentType(MediaType.TEXT_PLAIN)), appHandler::process);
    }

}

Handler class is as follows:

package com.test;

import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;



@Component
public class AppHandler {


    public Mono<ServerResponse> process(ServerRequest request){

        //Extract the request body
        Mono<String> responseBody = request.bodyToMono(String.class);
        responseBody.map(s -> s + " -- added on the server side.");

        return ServerResponse.ok()
                .body(responseBody.log(), String.class);

    }

    public Mono<ServerResponse> ping(ServerRequest request){
        return ServerResponse.ok()
                .contentType(MediaType.TEXT_PLAIN)
                .body(Mono.just("PONG").log(), String.class);
    }


}

extract of pom dependency

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.2</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    ...
<dependencies>

Upvotes: 0

Views: 1675

Answers (1)

Toerktumlare
Toerktumlare

Reputation: 14712

The error you have posted is not from the code you have posted. You are not allowed to block in a reactive application and you used the keyword block which means you are getting an IllegalStateException because blocking is illegal.

Then in the code you have posted, the problem is that you are breaking the chain.

responseBody.map(s -> s + " -- added on the server side.");

This line is just a declaration, but nothing happens until you subscribe, and nothing is subscribing to this line so you need to follow this up and take care of the return from the map function.

return responseBody.flatMap(s -> {
    return ServerResponse.ok()
        .body(Mono.just(s + " -- added on the server side."), String.class);
});

When a client calls your application they are subscribing, so you have to make sure that the chain is intact on the server side so that we can feed items out to the client. But you broke it by not handling the return in the row above, so then nothing happens.

Upvotes: 2

Related Questions