Welcome to my GitHub
https://github.com/zq2599/blog_demos
Content: Classification and summary of all original articles and supporting source code, involving Java, Docker, Kubernetes, DevOPS, etc.;
Overview of this article
As the fifth article in the "Spring Cloud Gateway Actual Combat" series, it’s time to understand the role of filters. In this article, let’s learn about the built-in filters of Spring Cloud Gateway. They are so versatile and powerful.
AddRequestHeader
- The AddRequestHeader filter, as the name implies, is to add the specified content to the request header
- Complete configuration with predicate:
server:
#服务端口
port: 8081
spring:
application:
name: hello-gateway
cloud:
gateway:
routes:
- id: path_route
uri: http://127.0.0.1:8082
predicates:
- Path=/hello/**
filters:
- AddRequestHeader=x-request-foo, bar-config
- Complete dynamic configuration with predicate:
[
{
"id": "path_route_addr",
"uri": "http://127.0.0.1:8082",
"predicates": [
{
"name": "Path",
"args": {
"pattern": "/hello/**"
}
}
],
"filters": [
{
"name": "AddRequestHeader",
"args": {
"name": "x-request-foo",
"value": "bar-dynamic"
}
}
]
}
]
- actual effect:
AddRequestParameter
- The AddRequestParameter filter, as the name implies, is to add request parameters
- The configuration is as follows, there will be an additional parameter in the request received by the service provider, named foo and value bar-config:
server:
#服务端口
port: 8081
spring:
application:
name: hello-gateway
cloud:
gateway:
routes:
- id: path_route
uri: http://127.0.0.1:8082
predicates:
- Path=/hello/**
filters:
- AddRequestParameter=foo, bar-config
- Complete dynamic configuration with predicate:
[
{
"id": "path_route_addr",
"uri": "http://127.0.0.1:8082",
"predicates": [
{
"name": "Path",
"args": {
"pattern": "/hello/**"
}
}
],
"filters": [
{
"name": "AddRequestParameter",
"args": {
"name": "foo",
"value": "bar-dynamic"
}
}
]
}
]
- actual effect:
AddResponseHeader
- The AddResponseHeader filter is to add parameters to the response header
- The configuration is as follows, the response received by the client will have an additional parameter in the header, named foo, and value bar-config-response:
server:
#服务端口
port: 8081
spring:
application:
name: hello-gateway
cloud:
gateway:
routes:
- id: path_route
uri: http://127.0.0.1:8082
predicates:
- Path=/hello/**
filters:
- AddResponseHeader=foo, bar-config-response
- Complete dynamic configuration with predicate:
[
{
"id": "path_route_addr",
"uri": "http://127.0.0.1:8082",
"predicates": [
{
"name": "Path",
"args": {
"pattern": "/hello/**"
}
}
],
"filters": [
{
"name": "AddResponseHeader",
"args": {
"name": "foo",
"value": "bar-dynamic-response"
}
}
]
}
]
- actual effect:
DedupeResponseHeader
- In the response header returned by the service provider, if a key has multiple values (for example, Access-Control-Allow-Origin in a cross-domain scenario), the DedupeResponseHeader filter can eliminate duplicate values. There are three elimination strategies. :RETAIN_FIRST (keep the first one, default), RETAIN_LAST (keep the last one), RETAIN_UNIQUE (de-duplicate)
- The configuration is as follows, the deduplication of the two header keys is specified, and the strategy is to keep the last one:
server:
#服务端口
port: 8081
spring:
application:
name: hello-gateway
cloud:
gateway:
routes:
- id: path_route
uri: http://127.0.0.1:8082
predicates:
- Path=/hello/**
filters:
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_LAST
DedupeResponseHeader
- In the response header returned by the service provider, if a key has multiple values (for example, Access-Control-Allow-Origin in a cross-domain scenario), the DedupeResponseHeader filter can eliminate duplicate values. There are three elimination strategies. :RETAIN_FIRST (keep the first one, default), RETAIN_LAST (keep the last one), RETAIN_UNIQUE (de-duplicate)
- The configuration is as follows, the deduplication of the two header keys is specified, and the strategy is to keep the last one:
server:
#服务端口
port: 8081
spring:
application:
name: hello-gateway
cloud:
gateway:
routes:
- id: path_route
uri: http://127.0.0.1:8082
predicates:
- Path=/hello/**
filters:
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_LAST
CircuitBreaker
- CircuitBreaker is a circuit breaker. Let’s experience this powerful function in a separate article.
FallbackHeaders
- FallbackHeaders are generally used in conjunction with CircuitBreaker. Look at the following configuration. After a circuit break occurs, the request will be forwarded to FallbackHeaders for processing. At this time, FallbackHeaders will add exception information to the key specified in the header:
spring:
cloud:
gateway:
routes:
- id: ingredients
uri: lb://ingredients
predicates:
- Path=//ingredients/**
filters:
- name: CircuitBreaker
args:
name: fetchIngredients
fallbackUri: forward:/fallback
- id: ingredients-fallback
uri: http://localhost:9994
predicates:
- Path=/fallback
filters:
- name: FallbackHeaders
args:
executionExceptionTypeHeaderName: Test-Header
MapRequestHeader
- MapRequestHeader is used to copy key-value pairs in the header. The following configuration means: if there is <font color="blue">Blue</font> in the request header, add the name <font color="red">X- The key of Request-Red</font> has the same value as the value of <font color="blue">Blue</font>
- The configuration is as follows, the deduplication of the two header keys is specified, and the strategy is to keep the last one:
server:
#服务端口
port: 8081
spring:
application:
name: hello-gateway
cloud:
gateway:
routes:
- id: path_route
uri: http://127.0.0.1:8082
predicates:
- Path=/hello/**
filters:
- MapRequestHeader=Blue, X-Request-Red
- As shown in the figure below, there is Blue in the request header:
- Looking at the service provider's log again, it shows that there is more X-Request-Red in the header:
- What happens if <font color="blue">X-Request-Red</font> already exists in the requested header? As shown in the figure below, we write <font color="blue">X-Request-Red</font> in the request header:
- At the interruption point of the service provider, you can find a magical scene. All the keys in the header and the corresponding values are actually collections, but in most cases there is only one element in the collection, and the new elements of MapRequestHeader will be put into this Collection, will not affect the original content:
PrefixPath
- PrefixPath is well understood, that is, when forwarding to the service provider, prefix the path
- For example, the original address of my service provider is <font color="blue"> http://127.0.0.1:8082/hello/str </font> The configuration is as follows, if I configure the gateway with PrefixPath=hello, then When accessing the gateway, <font color="blue">hello</font> is not needed in the request path, and the configuration is as follows:
server:
#服务端口
port: 8081
spring:
application:
name: hello-gateway
cloud:
gateway:
routes:
- id: path_route
uri: http://127.0.0.1:8082
predicates:
- Path=/str
filters:
- PrefixPath=/hello
- As shown in the figure below, the request path does not need to be <font color="blue">hello</font>:
PreserveHostHeader
- When PreserveHostHeader forwards the request to the service provider, it will retain the host information (otherwise it can only be determined by the HTTP client)
- First look at the effect of using PreserveHostHeader. As shown in the figure below, the host in the request header received by the service provider is the information configured by the gateway:
- Try adding PreserveHostHeader, the red box in the following figure is the real host information:
RequestRateLimiter
- RequestRateLimiter is used for current limiting and involves more content, so let’s put it in a separate chapter for further study.
RedirectTo
- The function of RedirectTo is simple and straightforward: Jump to the specified location. In the following configuration, the uri field is obviously an invalid address, but the request will still be forwarded to the specified location by RedirectTo:
server:
#服务端口
port: 8081
spring:
application:
name: hello-gateway
cloud:
gateway:
routes:
- id: path_route
uri: http://127.1.1.1:11111
predicates:
- Path=/hello/**
filters:
- RedirectTo=302, http://127.0.0.1:8082/hello/str
RemoveRequestHeader
- RemoveRequestHeader is well understood, delete the specified value in the request header
- The following configuration will delete foo in the request header:
server:
#服务端口
port: 8081
spring:
application:
name: hello-gateway
cloud:
gateway:
routes:
- id: path_route
uri: http://127.0.0.1:8082
predicates:
- Path=/hello/**
filters:
- RemoveRequestHeader=foo
RemoveResponseHeader
- RemoveResponseHeader deletes the specified value in the response header
- The following configuration will delete foo in the response header:
server:
#服务端口
port: 8081
spring:
application:
name: hello-gateway
cloud:
gateway:
routes:
- id: path_route
uri: http://127.0.0.1:8082
predicates:
- Path=/hello/**
filters:
- RemoveResponseHeader=foo
RemoveRequestParameter
- RemoveRequestParameter delete the specified parameter in the request parameter
- The following configuration will delete foo in the request parameters:
server:
#服务端口
port: 8081
spring:
application:
name: hello-gateway
cloud:
gateway:
routes:
- id: path_route
uri: http://127.0.0.1:8082
predicates:
- Path=/hello/**
filters:
- RemoveRequestParameter=foo1
RewritePath
- RewritePath is very practical, changing the path in the request parameters
- The following configuration will convert <font color="blue">/test/str</font> to <font color="blue">/hello/str</font>:
server:
#服务端口
port: 8081
spring:
application:
name: hello-gateway
cloud:
gateway:
routes:
- id: path_route
uri: http://127.0.0.1:8082
predicates:
- Path=/test/**
filters:
- RewritePath=/test/?(?<segment>.*), /hello/$\{segment}
- The request is as follows, it can be seen that the test in the path will be modified to hello by the gateway, which becomes the correct request path:
RewriteLocationResponseHeader
- RewriteLocationResponseHeader is used to rewrite the location information in the response
- The configuration is as follows, there are four parameters in total: stripVersionMode, locationHeaderName, hostValue, protocolsRegex
- For example, the request is <font color="blue">api.example.com/some/object/name</font>, and the location of the response is <font color="blue">object-service.prod.example.net/v2 /some/object/id</font>, will eventually be rewritten as <font color="blue">api.example.com/some/object/id</font> by the filter below
spring:
cloud:
gateway:
routes:
- id: rewritelocationresponseheader_route
uri: http://example.org
filters:
- RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,
- There are three strategies for stripVersionMode:
NEVER_STRIP: Do not execute
AS_IN_REQUEST: The original request is executed without vesion
ALWAYS_STRIP: fixed execution
- Location is used to replace the host:port part, if not, use the host in the Request
- protocolsRegex is used to match the protocol. If it fails to match, the name filter will do nothing.
RewriteResponseHeader
- RewriteResponseHeader is well understood: modify the response header, there are three parameters: the key of the header, the regular expression that matches the value, and the result of modifying the value
- The following configuration means to modify the value of the key <font color="blue">X-Response-Red</font> in the response header, find the content of password=xxx, and change it to password= *
server:
#服务端口
port: 8081
spring:
application:
name: hello-gateway
cloud:
gateway:
routes:
- id: path_route
uri: http://127.0.0.1:8082
predicates:
- Path=/test/**
filters:
- RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=***
SecureHeaders
- SecureHeaders will add a lot of security-related content to the response header, the configuration is as follows:
server:
#服务端口
port: 8081
spring:
application:
name: hello-gateway
cloud:
gateway:
routes:
- id: path_route
uri: http://127.0.0.1:8082
predicates:
- Path=/hello/**
filters:
- SecureHeaders
- The response is as follows, it can be seen that a lot of information has been added to the header:
- If you don’t want to return some of the content in the above picture, you can close it in the configuration file.
- Try again and get the following response. It can be seen that neither x-frame-options nor strict-transport-security returned:
SetPath
- SetPath is used with predicates, the following configuration will change the request <font color="blue">/test/str</font> to <font color="blue">/hello/str</font>, it can be seen that this segment is Assigned in predicates, and then used in filters:
server:
#服务端口
port: 8081
spring:
application:
name: hello-gateway
cloud:
gateway:
filter:
secure-headers:
disable:
- x-frame-options
- strict-transport-security
routes:
- id: path_route
uri: http://127.0.0.1:8082
predicates:
- Path=/test/{segment}
filters:
- SetPath=/hello/{segment}
SetRequestHeader
- SetRequestHeader, as the name implies, is to rewrite the request header, change the specified key to the specified value, and create it if the key does not exist:
server:
#服务端口
port: 8081
spring:
application:
name: hello-gateway
cloud:
gateway:
filter:
secure-headers:
disable:
- x-frame-options
- strict-transport-security
routes:
- id: path_route
uri: http://127.0.0.1:8082
predicates:
- Path=/hello/**
filters:
- SetRequestHeader=X-Request-Red, Blue
- Similar to SetPath, SetRequestHeader can also work with predicates. Variables defined in predicates can be used in SetRequestHeader. As shown below, when the request is /hello/str, the value of X-Request-Red in the header is <font color ="blue">Blue-str</font>:
server:
#服务端口
port: 8081
spring:
application:
name: hello-gateway
cloud:
gateway:
filter:
secure-headers:
disable:
- x-frame-options
- strict-transport-security
routes:
- id: path_route
uri: http://127.0.0.1:8082
predicates:
- Path=/hello/{segment}
filters:
- SetRequestHeader=X-Request-Red, Blue-{segment}
SetResponseHeader
- SetResponseHeader, as the name implies, is to rewrite the response header, change the specified key to the specified value, and create it if the key does not exist:
server:
#服务端口
port: 8081
spring:
application:
name: hello-gateway
cloud:
gateway:
filter:
secure-headers:
disable:
- x-frame-options
- strict-transport-security
routes:
- id: path_route
uri: http://127.0.0.1:8082
predicates:
- Path=/hello/**
filters:
- SetResponseHeader=X-Request-Red, Blue
SetStatus
- SetStatus is easy to understand: control returns code, the following settings will return 500:
server:
#服务端口
port: 8081
spring:
application:
name: hello-gateway
cloud:
gateway:
routes:
- id: path_route
uri: http://127.0.0.1:8082
predicates:
- Path=/hello/**
filters:
- SetStatus=500
- The test effect is as shown in the figure below. The content of the service provider will be returned normally, but the return code has been changed to 500:
- If you want to use SetStatus to modify the return code without losing the real return code, you can add the following configuration so that the real return code is named <font color="blue">original-status-header-name< /font>'s key:
server:
#服务端口
port: 8081
spring:
application:
name: hello-gateway
cloud:
gateway:
set-status:
original-status-header-name: aaabbbccc
routes:
- id: path_route
uri: http://127.0.0.1:8082
predicates:
- Path=/hello/**
filters:
- SetStatus=500
StripPrefix
- StripPrefix is a very commonly used filter. For example, the request is <font color="blue">/aaa/bbb/hello/str</font>, we need to convert it to <font color="blue">/hello/str </font>, just use <font color="blue">StripPrefix=2</font>, the first two levels of path have been deleted:
server:
#服务端口
port: 8081
spring:
application:
name: hello-gateway
cloud:
gateway:
set-status:
original-status-header-name: aaabbbccc
routes:
- id: path_route
uri: http://127.0.0.1:8082
predicates:
- Path=/aaa/**
filters:
- StripPrefix=2
- As shown in the figure below, the response is normal:
Retry
- As the name implies, Retry is a retry, and the following parameters are required:
- retries: number of retries
- statuses: What kind of return status is encountered before retrying, value reference: org.springframework.http.HttpStatus
- methods: Those types of methods will be retried (GET, POST, etc.), for value reference: org.springframework.http.HttpMethod
- series: What kind of series value is encountered before retrying, value reference: org.springframework.http.HttpStatus.Series
- exceptions: What kind of exceptions are encountered before retrying
- backoff: Retry strategy, composed of multiple parameters, such as firstBackoff
- The reference configuration is as follows:
spring:
cloud:
gateway:
routes:
- id: retry_test
uri: http://localhost:8080/flakey
predicates:
- Host=*.retry.com
filters:
- name: Retry
args:
retries: 3
statuses: BAD_GATEWAY
methods: GET,POST
backoff:
firstBackoff: 10ms
maxBackoff: 50ms
factor: 2
basedOnPreviousValue: false
RequestSize
- RequestSize is also very commonly used: to control the size of the request, you can use units such as <font color="blue">KB</font> or <font color="blue">MB</font>. If it exceeds this size, it will return a 413 error ( Payload Too Large),
spring:
cloud:
gateway:
routes:
- id: request_size_route
uri: http://localhost:8080/upload
predicates:
- Path=/upload
filters:
- name: RequestSize
args:
maxSize: 5000000
- Note that if RequestSize is not set, the default upper limit of Spring Cloud Gateway is <font color="red"> 5MB </font>
SetRequestHostHeader
- SetRequestHostHeader will modify the host value in the request header
- The following configuration will change the host in the request header to <font color="blue">aaabbb</font>
server:
#服务端口
port: 8081
spring:
application:
name: hello-gateway
cloud:
gateway:
routes:
- id: path_route
uri: http://127.0.0.1:8082
predicates:
- Path=/hello/**
filters:
- name: SetRequestHostHeader
args:
host: aaabbb
- At the break point in the code of the service provider, as shown in the figure below, it can be seen that the host has been changed to <font color="blue">aaabbb</font>
ModifyRequestBody
ModifyRequestBody is used to modify the body content of the request. The official recommendation here is to configure it with code. As shown below, the request body was originally a string, but the result was changed to an instance of the Hello object:
@Bean public RouteLocator routes(RouteLocatorBuilder builder) { return builder.routes() .route("rewrite_request_obj", r -> r.host("*.rewriterequestobj.org") .filters(f -> f.prefixPath("/httpbin") .modifyRequestBody(String.class, Hello.class, MediaType.APPLICATION_JSON_VALUE, (exchange, s) -> return Mono.just(new Hello(s.toUpperCase())))).uri(uri)) .build(); } static class Hello { String message; public Hello() { } public Hello(String message) { this.message = message; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
ModifyResponseBody
- ModifyResponseBody is similar to the previous ModifyRequestBody. The official recommendation is to implement it in code. The following code is used to change the content of the response body to all uppercase:
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("rewrite_response_upper", r -> r.host("*.rewriteresponseupper.org")
.filters(f -> f.prefixPath("/httpbin")
.modifyResponseBody(String.class, String.class,
(exchange, s) -> Mono.just(s.toUpperCase()))).uri(uri))
.build();
}
TokenRelay
- When using third-party authentication, such as OAuth2, use TokenRelay to forward the third-party token to the service provider:
spring:
cloud:
gateway:
routes:
- id: resource
uri: http://localhost:9000
predicates:
- Path=/resource
filters:
- TokenRelay=
- Remember to add the jar package dependency<font color="blue">org.springframework.boot:spring-boot-starter-oauth2-client</font>
Set up a global filter
- In the previous example, all filters are placed in the routing strategy and used with predicates. If you want to configure a globally effective filter, you can set the following settings in the configuration file. The following configuration means that AddResponseHeader and PrefixPath will process all requests. It has nothing to do with routing settings:
spring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Default-Red, Default-Blue
- PrefixPath=/httpbin
- At this point, we have already understood most of the built-in filters, and there are a few slightly more complicated ones that are left for in-depth study in later chapters.
You are not alone, Xinchen and original are with you all the way
- Java series
- Spring series
- Docker series
- kubernetes series
- Database + Middleware Series
- DevOps series
Welcome to pay attention to the public account: programmer Xin Chen
Search "Programmer Xin Chen" on WeChat, I am Xin Chen, and I look forward to traveling the Java world with you...
https://github.com/zq2599/blog_demos
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。