Spring WebClient Filters – Spring WebClient过滤器

最后修改: 2019年 8月 3日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we’re going to explore WebClient filters in Spring WebFlux, a functional, reactive web framework.

在本教程中,我们将探讨WebClient过滤器在Spring WebFlux,一个功能性、反应式Web框架。

2. Request Filters

2.要求过滤器

A filter can intercept, examine, and modify a client request (or response). Filters are very suitable for adding functionality to every single request since the logic stays in one place. Use cases include monitoring, modifying, logging, and authenticating client requests, just to mention a few.

过滤器可以拦截、检查和修改客户端请求(或响应)。过滤器非常适用于为每个请求添加功能,因为逻辑保持在一个地方。使用案例包括监控、修改、记录和验证客户端请求,仅举几例。

A request has an ordered chain of zero or more filters.

一个请求有一个由零个或多个过滤器组成的有序链。

In Spring Reactive, filters are instances of the functional interface ExchangeFilterFunction. The filter function has two parameters: the ClientRequest to modify and the next ExchangeFilterFunction.

在Spring Reactive中,过滤器是功能接口ExchangeFilterFunction的实例。过滤器函数有两个参数:要修改的ClientRequest和下一个ExchangeFilterFunction

Usually, a filter function returns by calling the next one in the filter chain:

通常情况下,一个过滤器函数通过调用过滤器链中的下一个函数返回。

ExchangeFilterFunction filterFunction = (clientRequest, nextFilter) -> {
    LOG.info("WebClient fitler executed");
    return nextFilter.exchange(clientRequest);
};

3. WebClient Filtering

3.WebClient过滤

After implementing a request filter, we have to “attach” it to the WebClient instance. This can be only done while creating the WebClient.

在实现了一个请求过滤器后,我们必须将其 “附加 “到WebClient实例上。这只能在创建WebClient时进行。

So then, let’s see how to create a WebClient. The first option is to invoke WebClient.create() with or without a base URL:

那么,让我们看看如何创建一个WebClient。第一个选择是调用WebClient.create(),无论是否有基本URL。

WebClient webClient = WebClient.create();

This, unfortunately, doesn’t allow to add a filter. The second option, then, is the one we’re looking for.

不幸的是,这不允许添加一个过滤器。那么,第二个选项就是我们要找的。

By using the WebClient.builder() we’re able to add filters:

通过使用WebClient.builder()我们能够添加过滤器

WebClient webClient = WebClient.builder()
  .filter(filterFunction)
  .build();

4. A Custom Filter

4.一个自定义的过滤器

Let’s start with a filter that counts the HTTP GET requests sent by the client.

让我们从一个计算客户端发送的HTTP GET请求的过滤器开始。

The filter examines the request method and increases a “global” counter in case of a GET request:

该过滤器检查请求方法,并在GET请求的情况下增加一个 “全局 “计数器。

ExchangeFilterFunction countingFunction = (clientRequest, nextFilter) -> {
    HttpMethod httpMethod = clientRequest.method();
    if (httpMethod == HttpMethod.GET) {
        getCounter.incrementAndGet();
    }
    return nextFilter.exchange(clientRequest);
};

The second filter we’ll define appends a version number to the request URL path. We utilize the ClientRequest.from() method to create a new request object from the current one and set the modified URL.

我们要定义的第二个过滤器是在请求的URL路径上附加一个版本号。我们利用ClientRequest.from()方法,从当前的请求对象创建一个新的请求对象,并设置修改后的URL。

Subsequently, we continue executing the filter chain with the new modified request object:

随后,我们用新修改的请求对象继续执行过滤链。

ExchangeFilterFunction urlModifyingFilter = (clientRequest, nextFilter) -> {
    String oldUrl = clientRequest.url().toString();
    URI newUrl = URI.create(oldUrl + "/" + version);
    ClientRequest filteredRequest = ClientRequest.from(clientRequest)
      .url(newUrl)
      .build();
    return nextFilter.exchange(filteredRequest);
};

Next, let’s define a filter to log the methods of sent requests along with their URLs. These details are available in the request object.

接下来,让我们定义一个过滤器来记录发送请求的方法以及它们的URL。这些细节可以在请求对象中找到。

All we have to do then is to print to some output stream:

那么我们要做的就是打印到某个输出流。

ExchangeFilterFunction loggingFilter = (clientRequest, nextFilter) -> {
    printStream.print("Sending request " + clientRequest.method() + " " + clientRequest.url());
    return nextFilter.exchange(clientRequest);
};

5. A Standard Filter

5.一个标准的过滤器

Finally, let’s look into basic authentication – a very common use case of request filtering.

最后,我们来看看基本认证–这是请求过滤的一个非常常见的用例。

The helper class ExchangeFilterFunctions offers the basicAuthentication() filter function which takes care of adding the authorization header to the request.

辅助类ExchangeFilterFunctions提供了basicAuthentication()过滤函数,它负责向请求添加authorization头。

As a result, we don’t need to define a filter for it:

因此,我们不需要为它定义一个过滤器。

WebClient webClient = WebClient.builder()
  .filter(ExchangeFilterFunctions.basicAuthentication(user, password))
  .build();

6. Conclusion

6.结语

In this short article, we have explored filtering WebFlux clients in Spring.

在这篇短文中,我们探讨了在Spring中过滤WebFlux客户端的问题。

As always, the code example can be found in over on GitHub.

一如既往,代码示例可以在GitHub上找到。