关于Spring Boot:Webflux Mono响应为空

webflux Mono response empty

我的项目中有一个非常简单的spring webflux rest端点。

1
2
3
4
5
6
@Bean
public RouterFunction authRoute() {
    return RouterFunctions.route(POST("/auth/signin").and(accept(APPLICATION_JSON)), this::signIn)
            .andRoute(POST("/auth/signup").and(accept(APPLICATION_JSON)), this::signUp)
            .andRoute(POST("/auth/test").and(accept(APPLICATION_JSON)), this::test);
}

/auth/test端点只需使用提供的用户名进行回复。

1
2
3
4
5
6
7
public Mono<ServerResponse> test(ServerRequest request) {
    System.out.println("Start test");
    Mono<JwtRequest> jwtRequestMono = request.bodyToMono(JwtRequest.class);
    jwtRequestMono.subscribe(v -> System.out.println(v.getUsername() +":" + v.getPassword()));
    return jwtRequestMono
            .flatMap(j -> ServerResponse.ok().contentType(APPLICATION_JSON).bodyValue(j.getUsername()));
}

terminal

我面临的问题是响应正文为空,应为用户名。我还验证了当我返回硬编码的字符串时,它可以通过。当我依赖jwtRequestMono.flatMap(...

时失败

![postman


这行几乎可以肯定是您的失败:

1
jwtRequestMono.subscribe(v -> System.out.println(v.getUsername() +":" + v.getPassword()));

您的请求不能被多次订阅-因此您在此行上对其进行订阅(它可以正常工作并按预期方式打印出值),然后框架对其进行订阅,然后它就崩溃了。我希望默认情况下会发生异常,并返回500响应,因此您很可能在某个地方吞下了异常。

切勿在自己的应用程序中订阅。那就是框架的工作。

相反,如果要在打印值时使用"副作用",请在响应链中使用doOnNext()

1
2
3
return jwtRequestMono
        .doOnNext(v -> System.out.println(v.getUsername() +":" + v.getPassword()))
        .flatMap(j -> ServerResponse.ok().contentType(APPLICATION_JSON).bodyValue(j.getUsername()));