[Hoxton.SR1 version] detailed explanation of Filter in Spring Cloud Gateway

catalogue

1, Introduction

2, Detailed explanation of commonly used Gateway Filter

3, Custom filter

4, Custom filter factory

5, Summary

1, Introduction

In the last article, we introduced the Gateway Predicate in detail. Let's take a look at the description of the Predicate on the official website: the Predicate assertion determines which route the request is processed by. Before the route processing, it needs to be processed by the pre filter of type "pre". After the processing returns the response, it can be processed by the post filter of type "post".

As can be seen from the above figure, after the Predicate assertion, it will go through the filter chain. We can modify the request or response in the filter, such as adding request header, response header and so on.

  • Filter function

Filter filter plays a very important role in the gateway. In the "pre" type filter, you can do parameter verification, permission verification, traffic monitoring, log output, protocol conversion, etc. in the "post" type filter, you can modify the response content and response header, log output, traffic monitoring, etc.

give an example:

Suppose there are three microservices: order service, payment service and commodity service. One of our requirements is to record the execution time of all requests. It is conceivable that each microservice needs to do the same thing, which is obviously not good. In microservices, all requests must be routed and forwarded through the gateway. In fact, we can record the request time in the gateway service, This greatly reduces the repeated code in each microservice and is also conducive to maintenance.

  • Filter declaration cycle

If you know about the old version of Spring Cloud Zuul gateway, you should know that ZuulFilter has the following four methods:

  • boolean shouldFilter(): whether the filter is released
  • Object run(): filter business execution principal method
  • String filterType(): the type of filter. pre and post are supported
  • filterOrder(): the order in which the filter is executed

In the new gateway of Spring Cloud Gateway, filter also supports "pre" and "post" filters. The client's request first passes through the "pre" type filter, and then forwards the request to the specific business service. After receiving the response from the business service, it is processed through the "post" type filter, and finally returns the response to the client.

2, Detailed explanation of commonly used Gateway Filter

Spring Cloud Gateway Filter official website address: https://docs.spring.io/spring-cloud-gateway/docs/2.2.4.RELEASE/reference/html/#gatewayfilter-factories

As you can see, the Spring Cloud official website provides as many as 30 filter factories:

Let's select some common Filter factories for detailed explanation. Before that, due to applicaiton The previous article on YML has too many configurations for Predicate assertions. Here we create a new module [springcloud-apigateway-gateway9528] to explain the Filter. Except for ports, other specific configurations are exactly the same as those in [springcloud-apigateway-gateway9527], which will not be explained here.

(1) The addrequestheader gateway filter factory: add a request header filter factory

[a] The payment service provider adds the following methods

/**
     * Test the gateway to forward the specified address and add the request header information
     */
    @GetMapping("/gatewayAddRequestHeader")
    public String gatewayAddRequestHeader(HttpServletRequest request) {
        String value = request.getHeader("X-Request-red");
        return "hello, [gatewayAddRequestHeader] the header[X-Request-red] is :" + value;
    }

[b]application.yml configuration

server:
  port: 9528
spring:
  application:
    name: springcloud-gateway
  cloud:
    gateway:
      routes:
        ########################################[AddRequestHeader GatewayFilter Add request header]######################################################
        - id: payment_service8001_gatewayAddRequestHeader  #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddRequestHeader/**
          filters:
            #Add the X-Request-red:blue header to the downstream request headers of all matching requests
            - AddRequestHeader=X-Request-red, blue


      discovery:
        locator:
          enabled: true   #Enable the function of dynamically creating routes from the registry, and use the microservice name for routing
eureka:
  instance:
    hostname: springcloud-gateway-service
  client:
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://springcloud-eureka7001.com:7001/eureka/,http://springcloud-eureka7002.com:7002/eureka/ #Cluster Eureka registry


[c] Testing

Browser access: http://localhost:9528/gatewayAddRequestHeader

It can be seen that the downstream service payment successfully obtained the value of the request header information [X-Request-red] added by the gateway.

 

(2) The addrequestparameter gateway filter factory: add a request parameter filter factory

[a] The payment service provider adds the following methods

/**
     * Test the gateway to forward the specified address and add request parameters
     */
    @GetMapping("/gatewayAddRequestParameter")
    public String gatewayAddRequestParameter(HttpServletRequest request) {
        String name = request.getParameter("name");
        return "hello, [gatewayAddRequestParameter] the name is :" + name;
    }

[b]application.yml configuration

server:
  port: 9528
spring:
  application:
    name: springcloud-gateway
  cloud:
    gateway:
      routes:
        ########################################[AddRequestHeader GatewayFilter Add request header]######################################################
        - id: payment_service8001_gatewayAddRequestHeader  #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddRequestHeader/**
          filters:
            #Add the X-Request-red:blue header to the downstream request headers of all matching requests
            - AddRequestHeader=X-Request-red, blue

      ########################################[AddRequestParameter GatewayFilter Add request parameter]######################################################
        - id: payment_service8001_gatewayAddRequestParameter #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddRequestParameter
          filters:  #Filters (filters: filters, filtering rules)
            # Add specified parameters
            - AddRequestParameter=name, weishihuai



      discovery:
        locator:
          enabled: true   #Enable the function of dynamically creating routes from the registry, and use the microservice name for routing
eureka:
  instance:
    hostname: springcloud-gateway-service
  client:
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://springcloud-eureka7001.com:7001/eureka/,http://springcloud-eureka7002.com:7002/eureka/ #Cluster Eureka registry


[c] Testing

Browser access: http://localhost:9528/gatewayAddRequestParameter

It can be seen that the downstream service payment successfully obtained the request parameter information added by the gateway. Note that it is a Get request.

 

(3) The AddResponseHeader GatewayFilter Factory: add a response header filter factory

[a] The payment service provider adds the following methods

    /**
     * Test the gateway to forward the specified address and add the response header
     */
    @GetMapping("/gatewayAddResponseHeader")
    public String gatewayAddResponseHeader() {
        return "hello, [gatewayAddResponseHeader] ";
    }

[b]application.yml configuration

server:
  port: 9528
spring:
  application:
    name: springcloud-gateway
  cloud:
    gateway:
      routes:
        ########################################[AddRequestHeader GatewayFilter Add request header]######################################################
        - id: payment_service8001_gatewayAddRequestHeader  #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddRequestHeader/**
          filters:
            #Add the X-Request-red:blue header to the downstream request headers of all matching requests
            - AddRequestHeader=X-Request-red, blue

        ########################################[AddRequestParameter GatewayFilter Add request parameter]######################################################
        - id: payment_service8001_gatewayAddRequestParameter #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddRequestParameter
          filters:  #Filters (filters: filters, filtering rules)
            # Add specified parameters
            - AddRequestParameter=name, weishihuai

        ########################################[AddResponseHeader GatewayFilter Add response header]######################################################
        - id: payment_service8001_gatewayAddResponseHeader #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddResponseHeader
          filters:  #filters: filters
            # Add specified parameters
            - AddResponseHeader=X-Response-Red, Blue



      discovery:
        locator:
          enabled: true   #Enable the function of dynamically creating routes from the registry, and use the microservice name for routing
eureka:
  instance:
    hostname: springcloud-gateway-service
  client:
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://springcloud-eureka7001.com:7001/eureka/,http://springcloud-eureka7002.com:7002/eureka/ #Cluster Eureka registry


[c] Testing

Browser access: http://localhost:9528/gatewayAddResponseHeader

It can be seen that the gateway successfully added the response header to the downstream service.

 

(4) The hystrix gateway filter factory

Hystrix is a library from Netflix that implements circuit breaker mode. The Hystrix GatewayFilter allows you to introduce circuit breakers for gateway routing, protect your services from cascading failures, and allow you to provide fallback responses in the event of downstream failures.

If you want to enable Hystrix GatewayFilters in your project, add a dependency on spring cloud starter Netflix hystrix on Spring Cloud Netflix.

The Hystrix GatewayFilter Factory requires a single name parameter, which is the name of the HystrixCommand. The Hystrix filter can also accept the optional fallbackUri parameter. Currently, only forward: schemed URIs are supported. If fallback is invoked, the request is forwarded to the controller that matches the URI.

[a] Add Hystrix dependency to gateway service

 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

[b] Main startup type open circuit breaker function

@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class GateWayServiceApplication9528 {
    public static void main(String[] args) {
        SpringApplication.run(GateWayServiceApplication9528.class, args);
    }
}

[c] The payment service provider adds the following methods

 /**
     * Test the gateway circuit breaker filter
     */
    @GetMapping("/gatewayHystrixGatewayFilter")
    public String gatewayHystrixGatewayFilter() {
        return "hello, [gatewayHystrixGatewayFilter] ";
    }

[d] Add gateway fallback controller

package com.wsh.springcloud.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Description: Filter failure callback Controller
 * @author: weishihuai
 * @Date: 2020/8/21 10:50
 */
@RestController
public class GatewayFallbackController {

    @GetMapping("/fallback")
    public String gatewayFallback() {
        return "sorry, gateway service is busy,please try again later!";
    }

}

[e]application.yml configuration

server:
  port: 9528
spring:
  application:
    name: springcloud-gateway
  cloud:
    gateway:
      routes:
        ########################################[AddRequestHeader GatewayFilter Add request header]######################################################
        - id: payment_service8001_gatewayAddRequestHeader  #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddRequestHeader/**
          filters:
            #Add the X-Request-red:blue header to the downstream request headers of all matching requests
            - AddRequestHeader=X-Request-red, blue

        ########################################[AddRequestParameter GatewayFilter Add request parameter]######################################################
        - id: payment_service8001_gatewayAddRequestParameter #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddRequestParameter
          filters:  #filters: filters
            # Add specified parameters
            - AddRequestParameter=name, weishihuai

        ########################################[AddResponseHeader GatewayFilter Add response header]######################################################
        - id: payment_service8001_gatewayAddResponseHeader #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddResponseHeader
          filters:  #filters: filters
            # Add specified parameters
            - AddResponseHeader=X-Response-Red, Blue

        ########################################[Hystrix GatewayFilter [circuit breaker]######################################################
        - id: payment_service8001_gatewayHystrixGatewayFilter #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayHystrixGatewayFilter
          filters:  #filters: filters
            - name: Hystrix
              args:
                name: fallbackcmd
                fallbackUri: forward:/fallback



      discovery:
        locator:
          enabled: true   #Enable the function of dynamically creating routes from the registry, and use the microservice name for routing
eureka:
  instance:
    hostname: springcloud-gateway-service
  client:
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://springcloud-eureka7001.com:7001/eureka/,http://springcloud-eureka7002.com:7002/eureka/ #Cluster Eureka registry


[f] Testing

Start the project and visit the browser: http://localhost:9528/gatewayHystrixGatewayFilter

It can be seen that the route was successfully forwarded. Let's stop the payment8001 service provider and visit again http://localhost:9528/gatewayHystrixGatewayFilter

It can be seen that the gateway follows the logic of the failed callback method localhost:9528/fallback. The above example is to use fallbackUri for an internal controller or handler within a gateway application. However, you can also reroute the request to a controller or handler in an external application, as follows:

[a] payment8001 add the following methods

 /**
     * External gateway failed callback
     */
    @GetMapping("/gatewayFallback")
    public String gatewayFallback() {
        return "sorry,this is outer gateway fallback ";
    }

    /**
     * External gateway failed callback
     */
    @GetMapping("/gatewayOuterFallbackHystrixGatewayFilter")
    public String gatewayOuterFallbackHystrixGatewayFilter() {
        return "hello,[gatewayOuterFallbackHystrixGatewayFilter]";
    }

[a]application.yml adjustment

server:
  port: 9528
spring:
  application:
    name: springcloud-gateway
  cloud:
    gateway:
      routes:
        ########################################[AddRequestHeader GatewayFilter Add request header]######################################################
        - id: payment_service8001_gatewayAddRequestHeader  #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddRequestHeader/**
          filters:
            #Add the X-Request-red:blue header to the downstream request headers of all matching requests
            - AddRequestHeader=X-Request-red, blue

        ########################################[AddRequestParameter GatewayFilter Add request parameter]######################################################
        - id: payment_service8001_gatewayAddRequestParameter #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddRequestParameter
          filters:  #filters: filters
            # Add specified parameters
            - AddRequestParameter=name, weishihuai

        ########################################[AddResponseHeader GatewayFilter Add response header]######################################################
        - id: payment_service8001_gatewayAddResponseHeader #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddResponseHeader
          filters:  #filters: filters
            # Add specified parameters
            - AddResponseHeader=X-Response-Red, Blue

        ########################################[Hystrix GatewayFilter [circuit breaker]######################################################
        - id: payment_service8001_gatewayHystrixGatewayFilter #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayHystrixGatewayFilter
          filters:  #filters: filters
            - name: Hystrix
              args:
                name: fallbackcmd
                fallbackUri: forward:/fallback

        - id: payment_service8001_outerFallback-gatewayHystrix #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayOuterFallbackHystrixGatewayFilter
          filters:  #filters: filters
            - name: Hystrix
              args:
                name: fallbackcmd
                fallbackUri: forward:/gatewayFallback  #This should correspond to the following - Path=/gatewayFallback
        - id: outer-gateway-fallback
          uri: http://localhost:8001
          predicates:
            #Method called when fallback http://localhost:8001/gatewayFallback
            - Path=/gatewayFallback


      discovery:
        locator:
          enabled: true   #Enable the function of dynamically creating routes from the registry, and use the microservice name for routing
eureka:
  instance:
    hostname: springcloud-gateway-service
  client:
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://springcloud-eureka7001.com:7001/eureka/,http://springcloud-eureka7002.com:7002/eureka/ #Cluster Eureka registry


[c] Testing

Start the project normally and visit the browser: http://localhost:9528/gatewayOuterFallbackHystrixGatewayFilter

It can be seen that the gateway successfully routes and forwards. Now let's manually trigger the gateway to fuse, modify it slightly, and add sleep for 10 seconds.

 /**
     * External gateway failed callback
     */
    @GetMapping("/gatewayOuterFallbackHystrixGatewayFilter")
    public String gatewayOuterFallbackHystrixGatewayFilter() throws InterruptedException {
        //Manually trigger gateway timeout fuse
        TimeUnit.SECONDS.sleep(10);
        return "hello,[gatewayOuterFallbackHystrixGatewayFilter]";
    }

Restart the project and visit again: http://localhost:9528/gatewayOuterFallbackHystrixGatewayFilter

It can be seen that the failed callback of the gateway has been rerouted to the controller or handler in the external application [localhost:8001/gatewayFallback here].

In this example, there is no / gatewayFallback callback endpoint or handler in the gateway application, but http://localhost:8001 There is a gatewayFallback failed callback in the application.

If the request is forwarded to the callback address, the Hystrix gateway filter also provides the Throwable that causes it. It acts as serverwebexchangeutils Hystrix_ EXECUTION_ EXCEPTION_ The attr attribute is added to ServerWebExchange and can be used when dealing with fallback in gateway applications.

For external controller / handler scenarios, you can add headers that contain exception details. You can FallbackHeaders GatewayFilter Factory Find more information about it in the section.

 

(5) The prefixpath gateway filter factory

The PrefixPath gateway filter factory accepts a prefix parameter. The following example configures a prefix path gateway filter:

[a] The payment service provider adds the following methods

/**
     * Test path prefix gateway filter factory
     */
    @GetMapping("/api/prefixPathGatewayFilter")
    public String prefixPathGatewayFilter() {
        return "hello,[prefixPathGatewayFilter]";
    }

[b]application.yml configuration

server:
  port: 9528
spring:
  application:
    name: springcloud-gateway
  cloud:
    gateway:
      routes:
        ########################################[AddRequestHeader GatewayFilter Add request header]######################################################
        - id: payment_service8001_gatewayAddRequestHeader  #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddRequestHeader/**
          filters:
            #Add the X-Request-red:blue header to the downstream request headers of all matching requests
            - AddRequestHeader=X-Request-red, blue

        ########################################[AddRequestParameter GatewayFilter Add request parameter]######################################################
        - id: payment_service8001_gatewayAddRequestParameter #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddRequestParameter
          filters:  #filters: filters
            # Add specified parameters
            - AddRequestParameter=name, weishihuai

        ########################################[AddResponseHeader GatewayFilter Add response header]######################################################
        - id: payment_service8001_gatewayAddResponseHeader #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddResponseHeader
          filters:  #filters: filters
            # Add specified parameters
            - AddResponseHeader=X-Response-Red, Blue

        ########################################[Hystrix GatewayFilter [circuit breaker]######################################################
        - id: payment_service8001_gatewayHystrixGatewayFilter #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayHystrixGatewayFilter
          filters:  #filters: filters
            - name: Hystrix
              args:
                name: fallbackcmd
                fallbackUri: forward:/fallback

        - id: payment_service8001_outerFallback-gatewayHystrix #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayOuterFallbackHystrixGatewayFilter
          filters:  #filters: filters
            - name: Hystrix
              args:
                name: fallbackcmd
                fallbackUri: forward:/gatewayFallback  #This should correspond to the following - Path=/gatewayFallback
        - id: outer-gateway-fallback
          uri: http://localhost:8001
          predicates:
            #Method called when fallback http://localhost:8001/gatewayFallback
            - Path=/gatewayFallback

        ########################################[PrefixPath  GatewayFilter [path prefix filter factory]######################################################
        - id: payment_service8001_prefixPathGatewayFilter #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/prefixPathGatewayFilter
          filters:  #filters: filters
            #The / api will be prefixed to all paths that match the request. Therefore, the request for / prefixPathGatewayFilter will be sent to / api/prefixPathGatewayFilter
            - PrefixPath=/api

      discovery:
        locator:
          enabled: true   #Enable the function of dynamically creating routes from the registry, and use the microservice name for routing
eureka:
  instance:
    hostname: springcloud-gateway-service
  client:
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://springcloud-eureka7001.com:7001/eureka/,http://springcloud-eureka7002.com:7002/eureka/ #Cluster Eureka registry


[c] Testing

Browser access: http://localhost:9528/prefixPathGatewayFilter

It can be seen that although the access address is http://localhost:9528/prefixPathGatewayFilter However, when the gateway forwards, it adds a path prefix / api, and the real requested interface should be http://localhost:8001/api/prefixPathGatewayFilter.

 

(6) The stripprefix gateway filter factory

The StripPrefix gateway filter factory accepts a parameter, parts. The parts parameter indicates the number of bits in the path to be intercepted from the URL in the request before sending the request downstream. The following example configures a StripPrefix gateway filter:

[a] The payment service provider adds the following methods

/**
     * Test gateway interception request
     */
    @GetMapping("/gatewayStripPrefix/{name}")
    public String gatewayStripPrefix(@PathVariable("name") String name) {
        return "hello, [gatewayStripPrefix] the name is :" + name + ", the server port is " + serverPort;
    }

[b]application.yml configuration

server:
  port: 9528
spring:
  application:
    name: springcloud-gateway
  cloud:
    gateway:
      routes:
        ########################################[AddRequestHeader GatewayFilter Add request header]######################################################
        - id: payment_service8001_gatewayAddRequestHeader  #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddRequestHeader/**
          filters:
            #Add the X-Request-red:blue header to the downstream request headers of all matching requests
            - AddRequestHeader=X-Request-red, blue

        ########################################[AddRequestParameter GatewayFilter Add request parameter]######################################################
        - id: payment_service8001_gatewayAddRequestParameter #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddRequestParameter
          filters:  #filters: filters
            # Add specified parameters
            - AddRequestParameter=name, weishihuai

        ########################################[AddResponseHeader GatewayFilter Add response header]######################################################
        - id: payment_service8001_gatewayAddResponseHeader #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddResponseHeader
          filters:  #filters: filters
            # Add specified parameters
            - AddResponseHeader=X-Response-Red, Blue

        ########################################[Hystrix GatewayFilter [circuit breaker]######################################################
        - id: payment_service8001_gatewayHystrixGatewayFilter #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayHystrixGatewayFilter
          filters:  #filters: filters
            - name: Hystrix
              args:
                name: fallbackcmd
                fallbackUri: forward:/fallback

        - id: payment_service8001_outerFallback-gatewayHystrix #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayOuterFallbackHystrixGatewayFilter
          filters:  #filters: filters
            - name: Hystrix
              args:
                name: fallbackcmd
                fallbackUri: forward:/gatewayFallback  #This should correspond to the following - Path=/gatewayFallback
        - id: outer-gateway-fallback
          uri: http://localhost:8001
          predicates:
            #Method called when fallback http://localhost:8001/gatewayFallback
            - Path=/gatewayFallback

        ########################################[PrefixPath  GatewayFilter [path prefix filter factory]######################################################
        - id: payment_service8001_prefixPathGatewayFilter #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/prefixPathGatewayFilter
          filters:  #filters: filters
            #The / api will be prefixed to all paths that match the request. Therefore, the request for / prefixPathGatewayFilter will be sent to / api/prefixPathGatewayFilter
            - PrefixPath=/api

        ########################################[StripPrefix GatewayFilter Factory Path interception filter factory]######################################################
        #The following configuration indicates that when accessing the request of localhost:9528/api/gatewayStripPrefix / * * the gateway intercepts the / api and distributes the request to http://localhost:8001 Go in
        - id: payment_service8001_gatewayStripPrefix #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            # The forwarding address format is URI / gatewaystripprefix, and the / API part will be intercepted by the following filter
            - Path=/api/gatewayStripPrefix/**
          filters:  #filters: filters
            # Intercept path bits, i.e. intercept / api
            - StripPrefix=1

      discovery:
        locator:
          enabled: true   #Enable the function of dynamically creating routes from the registry, and use the microservice name for routing
eureka:
  instance:
    hostname: springcloud-gateway-service
  client:
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://springcloud-eureka7001.com:7001/eureka/,http://springcloud-eureka7002.com:7002/eureka/ #Cluster Eureka registry


[c] Testing

Browser access: http://localhost:9528/api/gatewayStripPrefix/weishihuai

It can be seen that when the gateway forwards the request, it intercepts the / api, and the real access address in the downstream service is: http://localhost:8001/gatewayStripPrefix/weishihuai

 

(7) The rewritepath gateway filter factory

The RewritePath GatewayFilter factory accepts a path regexp parameter and a replacement parameter. It uses Java regular expressions to rewrite the request path in a flexible way. The following listing configures a RewritePath gateway filter:

[a] The payment service provider adds the following methods

 /**
     * Test path rewrite gateway filter factory
     */
    @GetMapping("/api/rewritePathGatewayFilter")
    public String rewritePathGatewayFilter() {
        return "hello, [rewritePathGatewayFilter]";
    }

[b]application.yml configuration

server:
  port: 9528
spring:
  application:
    name: springcloud-gateway
  cloud:
    gateway:
      routes:
        ########################################[AddRequestHeader GatewayFilter Add request header]######################################################
        - id: payment_service8001_gatewayAddRequestHeader  #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddRequestHeader/**
          filters:
            #Add the X-Request-red:blue header to the downstream request headers of all matching requests
            - AddRequestHeader=X-Request-red, blue

        ########################################[AddRequestParameter GatewayFilter Add request parameter]######################################################
        - id: payment_service8001_gatewayAddRequestParameter #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddRequestParameter
          filters:  #filters: filters
            # Add specified parameters
            - AddRequestParameter=name, weishihuai

        ########################################[AddResponseHeader GatewayFilter Add response header]######################################################
        - id: payment_service8001_gatewayAddResponseHeader #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddResponseHeader
          filters:  #filters: filters
            # Add specified parameters
            - AddResponseHeader=X-Response-Red, Blue

        ########################################[Hystrix GatewayFilter [circuit breaker]######################################################
        - id: payment_service8001_gatewayHystrixGatewayFilter #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayHystrixGatewayFilter
          filters:  #filters: filters
            - name: Hystrix
              args:
                name: fallbackcmd
                fallbackUri: forward:/fallback

        - id: payment_service8001_outerFallback-gatewayHystrix #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayOuterFallbackHystrixGatewayFilter
          filters:  #filters: filters
            - name: Hystrix
              args:
                name: fallbackcmd
                fallbackUri: forward:/gatewayFallback  #This should correspond to the following - Path=/gatewayFallback
        - id: outer-gateway-fallback
          uri: http://localhost:8001
          predicates:
            #Method called when fallback http://localhost:8001/gatewayFallback
            - Path=/gatewayFallback

        ########################################[PrefixPath  GatewayFilter [path prefix filter factory]######################################################
        - id: payment_service8001_prefixPathGatewayFilter #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/prefixPathGatewayFilter
          filters:  #filters: filters
            #The / api will be prefixed to all paths that match the request. Therefore, the request for / prefixPathGatewayFilter will be sent to / api/prefixPathGatewayFilter
            - PrefixPath=/api

        ########################################[StripPrefix GatewayFilter Factory Path interception filter factory]######################################################
        #The following configuration indicates that when accessing the request of localhost:9528/api/gatewayStripPrefix / * * the gateway intercepts the / api and distributes the request to http://localhost:8001 Go in
        - id: payment_service8001_gatewayStripPrefix #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            # The forwarding address format is URI / gatewaystripprefix, and the / API part will be intercepted by the following filter
            - Path=/api/gatewayStripPrefix/**
          filters:  #filters: filters
            # Intercept path bits, i.e. intercept / api
            - StripPrefix=1

        ########################################[RewritePath GatewayFilter Factory Path interception filter factory]######################################################
        #Rewrite the path of the request to / gateway / filter: 9528, and then configure the path of the request to / gateway: localhost in 95gateway / * * as follows: http://localhost:8001 Go in
        - id: payment_service8001_rewritePathGatewayFilter #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/api/rewritePathGatewayFilter
          filters:  #filters: filters
            - RewritePath=/api(?<segment>/?.*), $\{segment}

      discovery:
        locator:
          enabled: true   #Enable the function of dynamically creating routes from the registry, and use the microservice name for routing
eureka:
  instance:
    hostname: springcloud-gateway-service
  client:
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://springcloud-eureka7001.com:7001/eureka/,http://springcloud-eureka7002.com:7002/eureka/ #Cluster Eureka registry


For the request path of / api/rewritePathGatewayFilter, this will set the path to / rewritePathGatewayFilter before issuing the downstream request. Note that due to the YAML specification, $should be replaced with $\.

[c] Testing

Browser access: http://localhost:9528/api/rewritePathGatewayFilter

It can be seen that the gateway successfully rewrites the path when forwarding the route to the downstream service.

Seven commonly used filter factories were introduced earlier, and there are many on the official website. Due to time constraints, they will not be listed one by one here. Interested partners can go to the official website and try one by one according to the examples.  

3, Custom filter

Spring cloud gateway has built-in 19 kinds of powerful filter factories, which can meet the needs of many scenarios. Of course, you can customize your own filters. In spring cloud gateway, the filter needs to implement GatewayFilter and ordered interfaces.

The following two examples illustrate how to customize the filter in the Gateway gateway Gateway.

(1) Simple token verification filter

[a] payment8001 add the following methods

/**
     * Test custom rights gateway filter
     */
    @GetMapping("/customAuthFilter/{name}")
    public String customAuthFilter(@PathVariable("name") String name) {
        return "hello, [customAuthFilter] the name is :" + name + ", the server port is " + serverPort;
    }

[b] Custom permission check filter

package com.wsh.springcloud.filter;

import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * @version V1.0
 * @ClassName: com.wsh.springcloud.filter.CustomAuthFilter.java
 * @Description: Custom permission check filter
 * @author: weishihuai
 * @date: 2020/8/21 15:55
 * Note: judge whether there is token information in the request header. If
 */
public class CustomAuthFilter implements GatewayFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //Get the token in the request header
        String token = exchange.getRequest().getHeaders().getFirst("token");
        if (StringUtils.isNotBlank(token)) {
            //Execute next filter
            return chain.filter(exchange);
        } else {
            //token is empty, end
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

[c] Add custom filters to the Gateway Filter Factories.

Note: CustomAuthGatewayFilterFactory conforms to "CustomAuth" in xxgatewayfilterfactory, which is the configuration file application The name of the YML.

package com.wsh.springcloud.filter.factory;

import com.wsh.springcloud.filter.CustomAuthFilter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;

/**
 * @Description Filter factory
 * @Date 2020/8/21 20:40
 * @Author weishihuai
 * explain:
 */
@Component
public class CustomAuthGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> {
    @Override
    public GatewayFilter apply(Object config) {
        return new CustomAuthFilter();
    }
}

[d]application. Configure filter factory in YML

server:
  port: 9528
spring:
  application:
    name: springcloud-gateway
  cloud:
    gateway:
      routes:
        ########################################[AddRequestHeader GatewayFilter Add request header]######################################################
        - id: payment_service8001_gatewayAddRequestHeader  #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddRequestHeader/**
          filters:
            #Add the X-Request-red:blue header to the downstream request headers of all matching requests
            - AddRequestHeader=X-Request-red, blue

        ########################################[AddRequestParameter GatewayFilter Add request parameter]######################################################
        - id: payment_service8001_gatewayAddRequestParameter #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddRequestParameter
          filters:  #filters: filters
            # Add specified parameters
            - AddRequestParameter=name, weishihuai

        ########################################[AddResponseHeader GatewayFilter Add response header]######################################################
        - id: payment_service8001_gatewayAddResponseHeader #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddResponseHeader
          filters:  #filters: filters
            # Add specified parameters
            - AddResponseHeader=X-Response-Red, Blue

        ########################################[Hystrix GatewayFilter [circuit breaker]######################################################
        - id: payment_service8001_gatewayHystrixGatewayFilter #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayHystrixGatewayFilter
          filters:  #filters: filters
            - name: Hystrix
              args:
                name: fallbackcmd
                fallbackUri: forward:/fallback

        - id: payment_service8001_outerFallback-gatewayHystrix #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayOuterFallbackHystrixGatewayFilter
          filters:  #filters: filters
            - name: Hystrix
              args:
                name: fallbackcmd
                fallbackUri: forward:/gatewayFallback  #This should correspond to the following - Path=/gatewayFallback
        - id: outer-gateway-fallback
          uri: http://localhost:8001
          predicates:
            #Method called when fallback http://localhost:8001/gatewayFallback
            - Path=/gatewayFallback

        ########################################[PrefixPath  GatewayFilter [path prefix filter factory]######################################################
        - id: payment_service8001_prefixPathGatewayFilter #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/prefixPathGatewayFilter
          filters:  #filters: filters
            #The / api will be prefixed to all paths that match the request. Therefore, the request for / prefixPathGatewayFilter will be sent to / api/prefixPathGatewayFilter
            - PrefixPath=/api

        ########################################[StripPrefix GatewayFilter Factory Path interception filter factory]######################################################
        #The following configuration indicates that when accessing the request of localhost:9528/api/gatewayStripPrefix / * * the gateway intercepts the / api and distributes the request to http://localhost:8001 Go in
        - id: payment_service8001_gatewayStripPrefix #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            # The forwarding address format is URI / gatewaystripprefix, and the / API part will be intercepted by the following filter
            - Path=/api/gatewayStripPrefix/**
          filters:  #filters: filters
            # Intercept path bits, i.e. intercept / api
            - StripPrefix=1

        ########################################[RewritePath GatewayFilter Factory Path interception filter factory]######################################################
        #Rewrite the path of the request to / gateway / filter: 9528, and then configure the path of the request to / gateway: localhost in 95gateway / * * as follows: http://localhost:8001 Go in
        - id: payment_service8001_rewritePathGatewayFilter #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/api/rewritePathGatewayFilter
          filters:  #filters: filters
            - RewritePath=/api(?<segment>/?.*), $\{segment}

        ##########################################[Test custom permission filter]#################################################
        - id: payment_service8001_customAuthFilter #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/customAuthFilter/**
          filters:  #filters: filters
            - CustomAuth

      discovery:
        locator:
          enabled: true   #Enable the function of dynamically creating routes from the registry, and use the microservice name for routing
eureka:
  instance:
    hostname: springcloud-gateway-service
  client:
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://springcloud-eureka7001.com:7001/eureka/,http://springcloud-eureka7002.com:7002/eureka/ #Cluster Eureka registry


[e] Testing

Start the project and use postman to test:

It can be seen from the above that only when the token parameter is carried in the request header, the permission filter will be released, otherwise an error code will be returned.

 

(2) Filter for recording request time

[a] payment8001 add the following methods

/**
     * Test record request time filter
     */
    @GetMapping("/customRequestTimeFilter")
    public String customRequestTimeFilter(HttpServletRequest request) {
        String name = request.getParameter("name");
        return "hello, [customRequestTimeFilter], Received request parameters name:" + name;
    }

[b] Custom request time accumulation filter

package com.wsh.springcloud.filter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.Ordered;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * @Description: Custom request time record filter
 * @author: weishihuai
 * @Date: 2020/8/21 15:27
 */
public class CustomRequestTimeFilter implements GatewayFilter, Ordered {

    private static final Logger logger = LoggerFactory.getLogger(CustomRequestTimeFilter.class);

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String rawPath = exchange.getRequest().getURI().getRawPath();
        logger.info(rawPath + "-----------pre Preprocessing----------");
        long startTime = System.currentTimeMillis();

        return chain.filter(exchange).then().then(
                Mono.fromRunnable(() -> {
                    long endTime = System.currentTimeMillis();
                    logger.info(rawPath + "-----------post Post processing----------");
                    logger.info(exchange.getRequest().getURI().getRawPath() + "----> time consuming: " + (endTime - startTime) + "ms");
                })
        );
    }

    /**
     * Defines the order in which filters are executed
     */
    @Override
    public int getOrder() {
        return 0;
    }

}

[c] Custom RouteLocator # route locator configuration: configure a custom request filter to a request.

package com.wsh.springcloud.config;

import com.wsh.springcloud.filter.CustomRequestTimeFilter;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @version V1.0
 * @ClassName: com.wsh.springcloud.config.CustomRouteLocatorConfig.java
 * @Description: Custom route locator configuration
 * @author: weishihuai
 * @date: 2020/8/21 15:41
 */
@Configuration
public class CustomRouteLocatorConfig {

    @Bean
    public RouteLocator routes(RouteLocatorBuilder routeLocatorBuilder) {
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
        routes.route("payment8001_customRequestTimeFilter",     //Routing ID
                r -> r.path("/customRequestTimeFilter/**")  //Routing path regular expression
                        .filters(f -> f.filter(new CustomRequestTimeFilter())  //Custom request time record filter
                                .addRequestParameter("name", "weishihuai"))   //Add request parameters
                        .uri("http://localhost:8001 ") / / jump to the target service address
                        .order(0)
        ).build();
        return routes.build();
    }

}

[d] Testing

Start the project and visit the browser: http://localhost:9528/customRequestTimeFilter

View background log:

2020-08-21 21:09:41.471  INFO 10136 --- [ctor-http-nio-1] c.w.s.filter.CustomRequestTimeFilter     : /customRequestTimeFilter-----------pre Preprocessing----------
2020-08-21 21:09:41.486  INFO 10136 --- [ctor-http-nio-1] c.w.s.filter.CustomRequestTimeFilter     : /customRequestTimeFilter-----------post Post processing----------
2020-08-21 21:09:41.486  INFO 10136 --- [ctor-http-nio-1] c.w.s.filter.CustomRequestTimeFilter     : /customRequestTimeFilter----> time consuming: 15ms

It can be seen that the function of recording the request time of an interface has been successfully realized. It is recommended to configure this filter as a global filter in the project. After all, all requests can be recorded.  

4, Custom filter factory

In fact, in addition to custom filters, the Gateway also supports custom filter factory classes, so that we can configure filters in the configuration file.

The top-level interface of the filter factory is GatewayFilterFactory, which has two abstract classes close to the specific implementation:

  • AbstractGatewayFilterFactory
  • AbstractNameValueGatewayFilterFactory

The former of these two classes receives a parameter, such as its implementation class RedirectToGatewayFilterFactory; The latter receives two parameters, such as its implementation class AddRequestHeaderGatewayFilterFactory.

Next, we implement a filter factory. When recording the request time, we can set parameters to decide whether to print the request parameters.

[a] Custom filter factory

package com.wsh.springcloud.filter.factory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import reactor.core.publisher.Mono;

import java.util.Collections;
import java.util.List;

/**
 * @Description Custom factory request time
 * @Date 2020/8/21 21:27
 * @Author weishihuai
 * explain:
 */
public class CustomRequestTimeGatewayFilterFactory extends AbstractGatewayFilterFactory<CustomRequestTimeGatewayFilterFactory.Config> {

    private static final Logger logger = LoggerFactory.getLogger(CustomRequestTimeGatewayFilterFactory.class);

    public static final String SHOULD_PARAMS = "shouldParams";

    public CustomRequestTimeGatewayFilterFactory() {
        super(CustomRequestTimeGatewayFilterFactory.Config.class);
    }

    public List<String> shortcutFieldOrder() {
        return Collections.singletonList(SHOULD_PARAMS);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            String rawPath = exchange.getRequest().getURI().getRawPath();
            logger.info(rawPath + "-----------pre Preprocessing----------");
            long startTime = System.currentTimeMillis();
            return chain.filter(exchange).then(
                    Mono.fromRunnable(() -> {
                        long endTime = System.currentTimeMillis();
                        logger.info(rawPath + "-----------post Post processing----------");
                        StringBuilder sb = new StringBuilder(rawPath)
                                .append("--------> time consuming: ")
                                .append(endTime - startTime)
                                .append("ms");
                        if (config.isShouldParams()) {
                            sb.append(",Request parameters:").append(exchange.getRequest().getQueryParams());
                        }
                        logger.info(sb.toString());
                    })
            );
        };
    }

    public static class Config {
        /**
         * Whether to output parameters
         */
        boolean shouldParams;

        public Config() {
        }

        public boolean isShouldParams() {
            return shouldParams;
        }

        public void setShouldParams(boolean shouldParams) {
            this.shouldParams = shouldParams;
        }
    }

}

In the above code, an anonymous class of GatewayFilter is created in the apply(Config config) method. The specific implementation logic is the same as before, except that the logic of whether to print the request parameters is added, and the switch of this logic is Config isShouldParams(). The static internal class Config is to receive the parameter service of boolean type. The variable name can be written at will, but the method List shortcutFieldOrder() should be overridden. It should be noted that the constructor of the class must call the constructor of the lower parent class to pass the Config type, otherwise ClassCastException will be reported.

[b] Fill the filter factory into the IOC container

package com.wsh.springcloud.config;

import com.wsh.springcloud.filter.factory.CustomRequestTimeGatewayFilterFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Description Register custom filter factory
 * @Date 2020/8/21 21:37
 * @Author weishihuai
 * explain:
 */
@Configuration
public class CustomRequestTimeGatewayFilterFactoryConfig {
    @Bean
    public CustomRequestTimeGatewayFilterFactory customRequestTimeGatewayFilterFactory() {
        return new CustomRequestTimeGatewayFilterFactory();
    }
}

[c] payment8001 add the following methods

 /**
     * Test custom filter factory
     */
    @GetMapping("/customGatewayFilterFactory/{name}")
    public String customGatewayFilterFactory(@PathVariable("name") String name) {
        return "hello, [customGatewayFilterFactory] the name is :" + name + ", the server port is " + serverPort;
    }

[d]application. Add the following configuration to YML

server:
  port: 9528
spring:
  application:
    name: springcloud-gateway
  cloud:
    gateway:
      routes:
        ########################################[AddRequestHeader GatewayFilter Add request header]######################################################
        - id: payment_service8001_gatewayAddRequestHeader  #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddRequestHeader/**
          filters:
            #Add the X-Request-red:blue header to the downstream request headers of all matching requests
            - AddRequestHeader=X-Request-red, blue

        ########################################[AddRequestParameter GatewayFilter Add request parameter]######################################################
        - id: payment_service8001_gatewayAddRequestParameter #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddRequestParameter
          filters:  #filters: filters
            # Add specified parameters
            - AddRequestParameter=name, weishihuai

        ########################################[AddResponseHeader GatewayFilter Add response header]######################################################
        - id: payment_service8001_gatewayAddResponseHeader #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayAddResponseHeader
          filters:  #filters: filters
            # Add specified parameters
            - AddResponseHeader=X-Response-Red, Blue

        ########################################[Hystrix GatewayFilter [circuit breaker]######################################################
        - id: payment_service8001_gatewayHystrixGatewayFilter #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayHystrixGatewayFilter
          filters:  #filters: filters
            - name: Hystrix
              args:
                name: fallbackcmd
                fallbackUri: forward:/fallback

        - id: payment_service8001_outerFallback-gatewayHystrix #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/gatewayOuterFallbackHystrixGatewayFilter
          filters:  #filters: filters
            - name: Hystrix
              args:
                name: fallbackcmd
                fallbackUri: forward:/gatewayFallback  #This should correspond to the following - Path=/gatewayFallback
        - id: outer-gateway-fallback
          uri: http://localhost:8001
          predicates:
            #Method called when fallback http://localhost:8001/gatewayFallback
            - Path=/gatewayFallback

        ########################################[PrefixPath  GatewayFilter [path prefix filter factory]######################################################
        - id: payment_service8001_prefixPathGatewayFilter #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/prefixPathGatewayFilter
          filters:  #filters: filters
            #The / api will be prefixed to all paths that match the request. Therefore, the request for / prefixPathGatewayFilter will be sent to / api/prefixPathGatewayFilter
            - PrefixPath=/api

        ########################################[StripPrefix GatewayFilter Factory Path interception filter factory]######################################################
        #The following configuration indicates that when accessing the request of localhost:9528/api/gatewayStripPrefix / * * the gateway intercepts the / api and distributes the request to http://localhost:8001 Go in
        - id: payment_service8001_gatewayStripPrefix #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            # The forwarding address format is URI / gatewaystripprefix, and the / API part will be intercepted by the following filter
            - Path=/api/gatewayStripPrefix/**
          filters:  #filters: filters
            # Intercept path bits, i.e. intercept / api
            - StripPrefix=1

        ########################################[RewritePath GatewayFilter Factory Path interception filter factory]######################################################
        #Rewrite the path of the request to / gateway / filter: 9528, and then configure the path of the request to / gateway: localhost in 95gateway / * * as follows: http://localhost:8001 Go in
        - id: payment_service8001_rewritePathGatewayFilter #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/api/rewritePathGatewayFilter
          filters:  #filters: filters
            - RewritePath=/api(?<segment>/?.*), $\{segment}

        ##########################################[Test custom permission filter]#################################################
        - id: payment_service8001_customAuthFilter #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/customAuthFilter/**
          filters:  #filters: filters
            - CustomAuth

        ##########################################[Custom filter factory]#################################################
        - id: payment_service8001_customGatewayFilterFactory #Routing ID
          uri: http://localhost:8001 # specifies the access address of payment8001, that is, the routing address of the service provided after matching
          predicates:
            - Path=/customGatewayFilterFactory/**
          filters:  #filters: filters
            - CustomRequestTime=true

      discovery:
        locator:
          enabled: true   #Enable the function of dynamically creating routes from the registry, and use the microservice name for routing
eureka:
  instance:
    hostname: springcloud-gateway-service
  client:
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://springcloud-eureka7001.com:7001/eureka/,http://springcloud-eureka7002.com:7002/eureka/ #Cluster Eureka registry


[e] Testing

Start the project and visit the browser: http://localhost:9528/customGatewayFilterFactory/weishihuai?a=1&b=2

View background log:

2020-08-21 21:44:17.705  INFO 8488 --- [ctor-http-nio-3] .f.CustomRequestTimeGatewayFilterFactory : /customGatewayFilterFactory/weishihuai-----------pre Preprocessing----------
2020-08-21 21:44:17.728  INFO 8488 --- [ctor-http-nio-4] .f.CustomRequestTimeGatewayFilterFactory : /customGatewayFilterFactory/weishihuai-----------post Post processing----------
2020-08-21 21:44:17.729  INFO 8488 --- [ctor-http-nio-4] .f.CustomRequestTimeGatewayFilterFactory : /customGatewayFilterFactory/weishihuai--------> time consuming: 23ms,Request parameters:{a=[1], b=[2]}

It can be seen that we have successfully recorded the information of request parameters while recording the request time. The above is the implementation method of custom filter factory. For specific implementation, we can refer to the filter factory in the source code, such as RedirectToGatewayFilterFactory, AddRequestHeaderGatewayFilterFactory and so on.

5, Summary

In addition to summarizing some common filter usage methods, and explaining how to customize filters and custom filter factories through examples, we will summarize the global filter in gateway in the next article. I've put the codes of the above related projects on Gitee. If you need them, you can pull them for learning: https://gitee.com/weixiaohuai/springcloud_Hoxton , due to the limited level of the author, if there is anything wrong, please correct it, learn from each other and make progress together.

Tags: Spring Cloud filter gateway

Posted by turdferguson on Sat, 21 May 2022 07:03:25 +0300