如何在Spring引导FilterHandlerFunction中提交之前处理响应

时间:2018-03-04 11:41:29

标签: java spring-boot spring-webflux

我们正在将旧的Spring应用程序迁移到spring boot 2.0。

目前我们有一个拦截器,它在链中首先执行并执行以下操作:

  • ThreadLocal
  • 中设置唯一ID
  • 在提交响应之前,将从本地线程中删除唯一ID。

我试图想出一种在Spring WebFlux中实现这一点的方法。我可以使用WebFilter实现来做到这一点;但是,由于我使用RouterFunction作为控制器,我试图通过HandlerFilterFunction检查是否有办法实现此目的。

public class TxIdFilter implements HandlerFilterFunction<ServerResponse, ServerResponse> {
  /**
   * {@inheritDoc}
   */
  @Override
  public Mono<ServerResponse> filter(ServerRequest request, HandlerFunction<ServerResponse> next) {
    /*
     * How to achieve following (which can be done
     * using WebFilter)
     * 
     * exchange.getResponse().beforeCommit(() -> {
     *   logger.debug("Cleaning up the tx id...");
     *   AppTransactionContext.removeAll();
     *   return Mono.empty();
     * });
     */
    return next.handle(request);
  }
}

1 个答案:

答案 0 :(得分:1)

以下是您可以这样做的方法,虽然我在这里使用的是请求属性:

public class SampleFilterFunction implements HandlerFilterFunction {

    @Override
    public Mono filter(ServerRequest request, HandlerFunction next) {
        request.attributes().put("key", "value");
        return next.handle(request)
                .doOnSuccessOrError((value, error) -> request.attributes().remove("key"));
    }
}

你不应该依赖ThreadLocal,因为与Servlet Spring MVC模型不同,请求不依赖于特定的线程。请求处理可以在任何给定时间跳转到不同的线程。

Reactor provides a Context API for those uses cases

根据您的实际使用情况(我不确定此交易ID在此处的含义),您还可以查看Spring Cloud SleuthMicrometer以及他们如何解决问题各自的用例。