文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

实战Spring Cloud Gateway自定义谓词及网关过滤器

2024-11-29 23:44

关注

1. 简介

Spring Cloud Gateway 中,路由断言(predicates)和过滤器(filters)是两个核心概念,它们共同决定了如何处理进入网关的请求。

谓词工厂

谓词工厂用于定义路由断言。断言是路由的一个条件,只有当条件满足时,请求才会被路由到指定的服务。Spring Cloud Gateway 提供了一系列的内置断言,例如基于路径、请求头、请求方法等的断言。然而,如果你需要实现一些特定的业务逻辑或自定义条件,你可以创建自定义的谓词工厂。

自定义谓词工厂通常需要实现 org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory 或其子类,并定义断言的条件。在创建自定义谓词工厂时,你需要指定谓词的名字、配置类以及断言的匹配逻辑。

例如,你可以创建一个自定义谓词工厂来检查请求中是否包含特定的自定义请求头。

网关过滤器工厂

网关过滤器工厂用于定义在路由匹配后应用于请求的过滤器。这些过滤器可以对请求和响应进行修改,例如添加请求头、修改响应体或进行身份验证等。Spring Cloud Gateway 同样提供了一系列的内置过滤器,但同样,如果你需要实现特定的业务逻辑或自定义处理,你可以创建自定义的网关过滤器工厂。

自定义网关过滤器工厂通常需要实现 org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory,并定义过滤器的逻辑。你可以在这里编写 Java 代码来实现对请求和响应的自定义处理。

例如,你可以创建一个自定义网关过滤器工厂来记录每个请求的详细信息,或者根据特定的业务逻辑修改响应的内容。

2. 实战案例

2.1 自定义谓词工厂

该谓词工厂的作用检查请求参数及header中个性化的信息。

@Component
public class ParamHeaderRoutePredicateFactory extends AbstractRoutePredicateFactory {
  
  public static final String PARAM_KEY = "param";
  public static final String HEADER_KEY = "header" ;
  public static final String PARAM_VALUE = "pv" ;
  public static final String HEADER_VALUE = "hv" ;
  
  public ParamHeaderRoutePredicateFactory() {
    super(Config.class);
  }


  @Override
  public List shortcutFieldOrder() {
    return Arrays.asList(PARAM_KEY, PARAM_VALUE, HEADER_KEY, HEADER_VALUE) ;
  }


  @Override
  public Predicate apply(Config config) {
    return new GatewayPredicate() {
      @Override
      public boolean test(ServerWebExchange t) {
        String pv = t.getRequest().getQueryParams().getFirst(config.param) ;
        String hv = t.getRequest().getHeaders().getFirst(config.header) ;
        System.err.printf("请求参数: %s=%s, 请求头: %s=%s%n", config.param, pv, config.header, hv) ;
        return config.pv.equals(pv) && config.hv.equals(hv) ;
      }
    } ;
  }
  
  // 验证配置参数
  @Validated
  public static class Config {
    @NotEmpty(message = "参数param不能为空")
    private String param ;
    @NotEmpty(message = "请求header不能为空")
    private String header ;
    private String pv ;
    private String hv ;
    // getter, setter
  }
}

使用

spring:
  cloud:
    gateway:
      default-filters:
      - StripPrefix=1 
      routes:           
      - id: pack-lbs-1
        uri: packlb://cloudAppServiceProvider
        predicates:
        #- ParamHeader=q,java,v,1
        - name: ParamHeader
          args:
            param: q
            pv: java
            header: v
            hv: 1

请求中的q参数值必须是java,请求header中的v值必须是1,才会匹配该路径。

图片

2.2 自定义网关过滤器工厂

该过滤器的功能是改写请求参数信息。

@Component
public class CustomGatewayFilterFactory extends AbstractGatewayFilterFactory {
  
  public CustomGatewayFilterFactory() {
    super(Config.class) ;
  }
  
  @Override
  public List shortcutFieldOrder() {
    return super.shortcutFieldOrder() ;
  }


  @Override
  public GatewayFilter apply(Config config) {
    return (exchange, chain) -> {
      Route r = exchange.getAttribute(GATEWAY_ROUTE_ATTR) ;
      Map metadata = r.getMetadata() ;
      System.out.println(metadata) ;
      
      ServerHttpRequest request = exchange.getRequest() ;
      URI uri = request.getURI() ;  
      // 获取idNo参数,改写请求参数idNo数值
      MultiValueMap queryParams = request.getQueryParams();
      String idNo = queryParams.getFirst("idNo") ;
      // 对idNo参数进行解密操作(只是演示)
      idNo = idNo + "-new" ;
      // 这里为了演示简单,不考虑多个参数的情况
      String query = "idNo=" + idNo ;
      System.out.println(uri) ;
      URI newUri = UriComponentsBuilder.fromUri(uri).replaceQuery(query).build(true).toUri() ;
      System.out.println(newUri) ;
      Builder builder = request.mutate().uri(newUri) ;
      return chain.filter(exchange.mutate().request(builder.build()).build()) ;
    };
  }
  public static class Config {
  }
}

使用

spring:
  cloud:
    gateway:
      routes:
      - id: demo-service-01
        uri: http://localhost:8088
        predicates:
        - name: Path
          args:
            a: /api-x/**
        filters:
        - name: Custom

测试

图片

Spring Cloud Gateway 的自定义谓词工厂和网关过滤器工厂为开发者提供了灵活性和扩展性,使得开发者可以根据业务需求自定义路由条件和请求处理逻辑。通过实现这些自定义组件,你可以轻松地构建出满足特定业务需求的 API 网关。

以上是本篇文章全部内容,希望对你有帮助。

来源:Spring全家桶实战案例源码内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯