Home > Software engineering >  Body in serverRequest is null with ServerRequest(Spring Webflux)
Body in serverRequest is null with ServerRequest(Spring Webflux)

Time:06-10

I sent the request as below.

curl -d "{""key1"":""value1"", ""key2"":""value2""}" \
-H "Content-Type: application/json" \
-X POST http://localhost:8080/myApi/test

And write route configure as below

RouterFunctions.route()
               .path("/myApi", builder -> builder
                   .POST("/test", handler::test))
               .build();

In handler::test,

public Mono<ServerResponse> test(ServerRequest serverRequest) {
    System.out.println(serverRequest.headers());
    serverRequest.bodyToMono(String.class).subscribe(System.out::println);
    return  ServerResponse.ok().body(Mono.just("ok"), String.class);
}

But result is as below.

[Host:"localhost:8080", User-Agent:"curl/7.77.0", Accept:"*/*", Content-Type:"application/json", content-length:"26"]

I add one line to check body is null, and result is as below.

System.out.println(serverRequest.bodyToMono(String.class).toProcessor().peek());
null

Is there any way to extract body from ServerRequest?

CodePudding user response:

You are not supposed to subscribe explicitly to the publisher in WebFlux. If you run in debug mode and put breakpoint on return statement you would see

Caused by: java.lang.IllegalStateException: Only one connection receive subscriber allowed.

In run-time this error is not visible because subscribe is async and your code exited even before it.

In any case, the correct implementation would look like

public Mono<ServerResponse> test(ServerRequest serverRequest) {
    return serverRequest.bodyToMono(String.class)
            .doOnNext(System.out::println)
            .flatMap(body -> ServerResponse.ok()
                    .body(BodyInserters.fromValue("ok"))
            );
}
  • Related