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(); }