java - Spring WebFlux : How to access Request Body in HandlerFilterFunction

标签 java filter reactive-programming spring-webflux reactor-netty

我正在尝试从 WebFlux 的 HandlerFunctionFunction 访问请求正文,但我收到了 java.lang.IllegalStateException: Only one connection receive subscriber allowed.

我想做类似于下面代码块的事情

public class ExampleHandlerFilterFunction 
  implements HandlerFilterFunction<ServerResponse, ServerResponse> {

    @Override
    public Mono<ServerResponse> filter(ServerRequest serverRequest,
      HandlerFunction<ServerResponse> handlerFunction) {
        if (serverRequest.pathVariable("name").equalsIgnoreCase("test")) {
            return serverRequest.bodyToMono(Player.class)
             .doOnNext(loggerService :: logAndDoSomethingElse)
             .then(handlerFunction.handle(serverRequest);
        }
        return handlerFunction.handle(serverRequest);
    }
}

我也尝试了 serverRequest.bodyToMono(Player.class).cache(),但没有成功。

更新:添加处理程序和路由器功能

处理函数

@Component
public class PlayerHandler {

    @Autowired
    private final playerRepository;

    public PlayerHandler(PlayerRepository palyerRepository) {

       this.palyerRepository = playerRepository;
    }

    public Mono<ServerResponse> savePlayer(ServerRequest request) {

        Mono<String> id = request.bodyToMono(Player.class)
        .map(playerRepository::save)
        .map(Player::getId);

        return ok().body(id, String.class);
    }
}

路由器功能


@Bean
public RouterFunction<ServerResponse> route(PlayerHandler playerHandler) {
    return RouterFunctions
      .route(POST("/players/"), playerHandler::save)
      .filter(new ExampleHandlerFilterFunction());
}

记录器服务


public Mono<Void> T logAndDoSomethingElse(T t){
    ---- auditing business logic----
    return loggerRepository.save(asJsonb);
}

有人可以帮助我吗?谢谢

最佳答案

import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.HandlerFilterFunction;
import org.springframework.web.reactive.function.server.HandlerFunction;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;

@Component
public class FundsAuthorizationFilter implements HandlerFilterFunction<ServerResponse, ServerResponse> {

    @Override
    public Mono<ServerResponse> filter(ServerRequest request, HandlerFunction<ServerResponse> handlerFunction) {
        String block = request.bodyToMono(String.class).block();
        JSONObject jsonObj = new JSONObject(block);
        ServerRequest.Builder newRequestBuilder = ServerRequest.from(request);
        newRequestBuilder.body(block);

        return handlerFunction.handle(newRequestBuilder.build());
    }

}

我找到了一个解决方案,那就是克隆 serverRequest 并将正文设置为新请求

关于java - Spring WebFlux : How to access Request Body in HandlerFilterFunction,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57385092/

相关文章:

java - 从 ActionPerformed 调用方法并在主线程上运行它

java - 如何实现具有不同参数数量的抽象方法

java - 在actionPerformed()方法中创建一个新的JFrame,然后我如何使用这个JFrame的JButton执行操作

android - 我应该如何用字符串过滤相应的复选框

javascript - 有条件地应用点击时更改的类

java - 使用 gzip 格式的缓冲区解压缩图像失败

带 $and 运算符和不带运算符的条件之间的 Mongodb 区别

javascript - 使用 Angular - 不显示基于其他数组项目的 Ng-Repeat 数组项目

java - 如何在 RxJava 中返回聚合——collect() 是正确的方法吗?

ios - RxSwift,如何应用背压以串行显示 Stream 中每个项目的 UIAlertView