5.20 StripPrefix GatewayFilter Factory
這個過濾器的工廠的實現類是:StripPrefixGatewayFilterFactory,它需要配置一個參數 parts,這個parts是一個int值,表示從請求的路徑中跳過的路徑個數,比如請求路徑是/a/b/c,如果parts =2,那么請求在轉發前就會變成/c,直接跳過前面的兩個路徑。
在application.yml的配置中如下所示:
spring: cloud: gateway: routes: - id: nameRoot uri: http://nameservice predicates: - Path=/name/** filters: - StripPrefix=2
當請求路徑/name/bar/foo通過網關向nameserivce的服務轉發時,請求路徑將會轉變為 http://nameserivice/foo,這個過濾器的用途可以用來重新定義新的轉發路徑。有時候網關需要的url和后面的服務的url可能是不一致的,或者一些路徑只會在網關中用到,比如做為斷言使用,但是后面的服務並不需要,因此可以使用這個過濾器工作跳過不需要的路徑。
5.21 Retry GatewayFilter Factory
這個過濾器工廠的實現類是:RetryGatewayFilterFactory,它有三個可以配置的參數,如下所示:
- retries: 配置需要嘗試重新請求的次數
- statuses: 配置需要嘗試重新請求的Http狀態碼,它必須是
org.springframework.http.HttpStatus
枚舉中定義的值或枚舉名字 - series: 配置需要嘗試重新請求的series狀態碼,它必須是
org.springframework.http.HttpStatus.Series枚舉中的值或枚舉的名字
- methods: 配置需要嘗試重新請求的Http方法名,它必須是
org.springframework.http.HttpMethod
枚舉中的值
在application.yml中的配置如下所示:
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
注意:目前這個過濾器不支持帶消息體的重試操作,例如POST或PUT這樣可以帶body的請求。這是為了避免重復提交信息。
另外,如果在過濾器中在URL之前使用了forward:前綴,那么在編碼接收請求的服務時,需要特別小心。如果出現了錯誤,應該將它提交並返回給請求的客戶端。比如,如果一個請求的服務是一個注解標記的controller控制器,如果出現了錯誤,不要返回一個帶錯誤碼的ReponseEntity,而應該拋出異常或者使用Mono.error(ex)返回,這樣retry過濾器就可以捕獲並重試了。
5.22 RequestSize GatewayFilter Factory
這個過濾器的實現類是:RequestSizeGatewayFilterFactory,當請求的數據大於配置的允許的值時,它可以限制到達下游服務的請求。可以配置RequestSize參數,指定允許請求的數據量的最大值,它的單位是byte。
在application.yml中的配置如下所示:
spring: cloud: gateway: routes: - id: request_size_route uri: http://localhost:8080/upload predicates: - Path=/upload filters: - name: RequestSize args: maxSize: 5000000
如果請求的數據量大於允許的值,服務會返回狀態碼413 Payload Too Large,並且在返回的包頭信息中返回一個錯誤信息:
errorMessage : Request size is larger than permissible limit. Request size is 6.0 MB where permissible limit is 5.0 MB
注意,如果添加了這個過濾器,而沒有指定RequestSize參數的大小,它的默認值就是5M。
這個過濾器可以用來限制文件上傳時限制上傳文件的大小,防止數據量過載
5.23 Modify Request Body GatewayFilter Factory
這個過濾器的實現類是:ModifyRequestBodyGatewayFilterFactory,它只能通過Java代碼添加,不能使用application.yml配置,並且,這個過濾器還處於Beta階段,在后期的版本中有可能被修改。它可以在請求轉發到下游服務之前,對請求的數據進行修改,如下面代碼所示:
@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();//這里的修改是把一個字符串放到一個對象中,並轉化為json } 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; } }
5.24 Modify Response Body GatewayFilter Factory
這個過濾器的實現類是:ModifyResponseBodyGatewayFilterFactory,它只能通過Java代碼添加,不能通過application.yml配置。並且這個過濾器還處於beta版本中,后期版本可能會修改它。它可以在數據返回給客戶端之后,對消息體進行修改,如下面代碼所示:
@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(); }