Backend Development 7 min read

How to Build Custom Predicate and Filter Factories in Spring Cloud Gateway

This article explains how to create custom predicate and gateway filter factories in Spring Cloud Gateway, covering the underlying concepts, implementation steps, example code, and YAML configuration to tailor routing conditions and request handling for specific business needs.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
How to Build Custom Predicate and Filter Factories in Spring Cloud Gateway

Environment

Spring Boot 2.7.12 with Spring Cloud 2021.0.7.

1. Introduction

In Spring Cloud Gateway, predicates and filters are core concepts that determine how incoming requests are processed.

Predicate Factory

Predicate factories define routing predicates. A predicate is a condition that must be satisfied for a request to be routed to a service. Spring Cloud Gateway provides built‑in predicates (path, header, method, etc.) but you can create custom ones by extending org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory and implementing the matching logic.

Custom Predicate Example

The following example shows a custom predicate factory that checks a request query parameter and a header.

<code>@Component
public class ParamHeaderRoutePredicateFactory extends AbstractRoutePredicateFactory<ParamHeaderRoutePredicateFactory.Config> {
  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<String> shortcutFieldOrder() {
    return Arrays.asList(PARAM_KEY, PARAM_VALUE, HEADER_KEY, HEADER_VALUE);
  }

  @Override
  public Predicate<ServerWebExchange> 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
  }
}
</code>

YAML configuration to use the custom predicate:

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

The request matches only when the query parameter q equals java and the header v equals 1 .

2. Custom Gateway Filter Factory

Filter factories define processing that occurs after a route matches. They can modify the request or response. Custom filters are created by extending org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory .

Custom Filter Example

The example rewrites a request parameter idNo .

<code>@Component
public class CustomGatewayFilterFactory extends AbstractGatewayFilterFactory<Config> {

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

  @Override
  public List<String> shortcutFieldOrder() {
    return super.shortcutFieldOrder();
  }

  @Override
  public GatewayFilter apply(Config config) {
    return (exchange, chain) -> {
      Route r = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
      Map<String, Object> metadata = r.getMetadata();
      System.out.println(metadata);

      ServerHttpRequest request = exchange.getRequest();
      URI uri = request.getURI();
      // Get idNo parameter and rewrite its value
      MultiValueMap<String, String> queryParams = request.getQueryParams();
      String idNo = queryParams.getFirst("idNo");
      // Simple demo transformation
      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 {
  }
}
</code>

YAML configuration to register the custom filter:

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

Conclusion: Custom predicate and filter factories give developers flexibility and extensibility, allowing them to tailor routing conditions and request‑handling logic to meet specific business requirements in Spring Cloud Gateway.

Javabackend developmentSpring Cloud GatewayCustom FilterCustom Predicate
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.