SpringCloud gateway内置过滤器之六

1、RequestSize GatewayFilter

当请求大小大于允许的限制时,RequestSize GatewayFilter可以限制请求到达下游服务。过滤器采用maxSize参数。maxSize是`DataSize类型,因此可以将值定义为一个数字,后跟可选的DataUnit后缀,如“KB”或“MB”。字节的默认值为“B”。它是以字节为单位定义的请求的允许大小限制。当请求因大小而被拒绝时,RequestSize GatewayFilter将响应状态设置为413 Payload Too Large(413有效负载太大),并带有额外的标头errorMessage。

spring:
  cloud:
    gateway:
      enabled: true
      routes:
        - id: Goods-Server  # 路由 id,唯一标识
          uri: lb://producer
          predicates:
            #  - Path=/**  # 断言,路由匹配条件,匹配 /product 开头的所有 api
              - Path=/producer/{segment}
          filters:
              - StripPrefix=1
              - name: RequestSize
                args:
                  maxSize: 50

设置了请求最大大小是50B。用Postman调用http://localhost:8500/producer/hello,选择一个超过50B的文件上传:

 

可以看到响应错误消息(Request size is larger than permissible limit. Request size is 1.4 kB where permissible limit is 50 B)和响应状态码(413)。

2、SetRequestHostHeader GatewayFilter

SetRequestHostHeader GatewayFilter设置请求Host头。

spring:
  cloud:
    gateway:
      enabled: true
      routes:
        - id: Goods-Server  # 路由 id,唯一标识
          uri: lb://producer
          predicates:
            #  - Path=/**  # 断言,路由匹配条件,匹配 /product 开头的所有 api
              - Path=/producer/{segment}
          filters:
              - StripPrefix=1
              - name: SetRequestHostHeader
                args:
                    host: example.org

修改Producer模块的Controller:

@RequestMapping("/hello")
public String hello(String name, HttpServletRequest request, HttpServletResponse response) {
    System.out.println(request.getHeader("Host"));
    return "hello," + name + "," + port;
}

访问http://localhost:8500/producer/hello,从Producer模块控制台看到输出example.org。

3、Modify a Request Body GatewayFilter

可以使用ModifyRequestBody GatewayFilter在网关向下游发送请求体之前对其进行修改。

 

在GatewayServer模块的配置类中加入:

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {

    return builder.routes()
            .route("rewrite_request_obj", r ->  r.path("/producer/**")
                    .filters(f -> f.stripPrefix(1).modifyRequestBody(String.class, Map.class, MediaType.APPLICATION_JSON_VALUE, (exchange, s) -> {
                        Map<String,Object> map = null;
                        try {
                            System.out.println("value:"+s);
                            map = objectMapper.readValue(s, Map.class);
                        } catch (JsonProcessingException e) {
                            throw new RuntimeException(e);
                        }

                        map.put("sex","男");
                        return Mono.just(map);
                    })).uri("lb://producer")).build();
}

用函数端点的方式配置了ModifyRequestBody GatewayFilter。router id是rewrite_request_obj,当请求url是/producer/**才处理。modifyRequestBody更改了请求体并加了sex=男的字段,并将请求转发到lb://producer。

 

修改Producer模块的Controller:

@RequestMapping("/hello")
public String hello(String name, HttpServletRequest request, HttpServletResponse response, @RequestBody String s) {
    ObjectMapper objectMapper = new ObjectMapper();
    try {
        Map<String,Object> map = objectMapper.readValue(s, Map.class);
        for (Map.Entry<String, Object> stringObjectEntry : map.entrySet()) {
            System.out.println("key:"+stringObjectEntry.getKey()+":value="+stringObjectEntry.getValue());
        }
    } catch (JsonProcessingException e) {
        throw new RuntimeException(e);
    }

    return "hello," + name + "," + port;
}

用Postman调用http://localhost:8500/producer/hello:

 

 

查看Producer控制台:

4、Modify a Response Body GatewayFilter

ModifyResponseBody filter 更改响应体。

 

在GatewayServer模块的配置类中加入:

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {

    return builder.routes()
            .route("rewrite_request_obj", r ->  r.path("/producer/**")
                    .filters(f -> f.stripPrefix(1).modifyRequestBody(String.class, Map.class, MediaType.APPLICATION_JSON_VALUE, (exchange, s) -> {
                        Map<String,Object> map = null;
                        try {
                            System.out.println("value:"+s);
                            map = objectMapper.readValue(s, Map.class);
                        } catch (JsonProcessingException e) {
                            throw new RuntimeException(e);
                        }

                        map.put("sex","男");
                        return Mono.just(map);
                    }).modifyResponseBody(String.class,String.class,MediaType.APPLICATION_JSON_VALUE,((serverWebExchange, s) -> {
                        return Mono.just(s + ",hello");
                            }))
                    ).uri("lb://producer")).build();
}

modifyResponseBody方法在响应体后面增加了",hello"字符串。用Postman调用http://localhost:8500/producer/hello:
 

 

可以看到结果已修改。

5、Token Relay GatewayFilter

令牌转发是OAuth2使用者充当客户端并将传入令牌转发给资源请求的地方。使用者可以是纯客户端(如SSO应用程序)或资源服务器。要添加依赖org.springframework.boot:spring-boot-starter-oauth2-client.

spring:
  cloud:
    gateway:
      routes:
      - id: resource
        uri: http://localhost:9000
        predicates:
        - Path=/resource
        filters:
        - TokenRelay=

6、默认过滤器

要将过滤器应用于所有路由,可以使用spring.cloud.gateway.default-filters。

spring:
  cloud:
    gateway:
      default-filters:
      - AddResponseHeader=X-Response-Default-Red, Default-Blue
      - PrefixPath=/httpbin
posted @ 2023-05-06 22:36  shigp1  阅读(626)  评论(0)    收藏  举报