Cloud Native 8 min read

How to Implement and Combine Global & Gateway Filters in Spring Cloud Gateway

This guide explains the purpose, signatures, and ordering of GlobalFilter and GatewayFilter in Spring Cloud Gateway, shows how to combine them, and provides detailed code examples for custom global filters, forward routing, load‑balancing, Netty, WebSocket, and other core filters, including configuration tips.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
How to Implement and Combine Global & Gateway Filters in Spring Cloud Gateway

Overview

GlobalFilter and GatewayFilter share the same method signature. These special filters are conditionally applied to all routes.

In future milestone releases, this interface and its usage may change.

GlobalFilter is a contract for intercepting web requests in a chain, useful for cross‑cutting, application‑independent concerns such as security or timeout.

public interface GlobalFilter {
  /**
   * Process the web request and optionally delegate to the next filter via the given GatewayFilterChain.
   * @param exchange the current server exchange
   * @param chain provides a way to delegate to the next filter
   * @return Mono<Void> to indicate when request processing is complete
   */
  Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}

Combining Global and Gateway Filters

When a request matches a route, the filter chain is built by adding all GlobalFilter instances and the route‑specific GatewayFilter instances. The chain is ordered using org.springframework.core.Ordered; you can set the order by implementing getOrder().

The highest‑priority filter runs first in the "pre" phase, and the lowest‑priority filter runs last in the "post" phase.

@Bean
public GlobalFilter customFilter() {
  return new CustomGlobalFilter();
}

public class CustomGlobalFilter implements GlobalFilter, Ordered {

  @Override
  public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    log.info("custom global filter");
    return chain.filter(exchange);
  }

  @Override
  public int getOrder() {
    return -1;
  }
}

Forward Routing Filter

The ForwardRoutingFilter looks for the URI in ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR. If the URL is in forward mode (e.g., forward:///path), it forwards the request to Spring's DispatcherHandler. The original URL is stored in ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR.

Load‑Balancing Filter

The ReactiveLoadBalancerClientFilter checks ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR. If the URL uses the lb scheme (e.g., lb://myservice), it resolves the service name via Spring Cloud Reactor LoadBalancer and replaces the URI. The original URL is saved in GATEWAY_ORIGINAL_REQUEST_URL_ATTR. It also examines GATEWAY_SCHEME_PREFIX_ATTR to apply scheme‑specific rules.

spring:
  cloud:
    gateway:
      routes:
      - id: myRoute
        uri: lb://service
        predicates:
        - Path=/service/**
By default, when the ReactorLoadBalancer cannot find a service instance, it returns 503. Setting spring.cloud.gateway.loadbalancer.use404=true makes the gateway return 404 instead. If the ServiceInstance.isSecure flag differs from the incoming request scheme, the downstream request scheme is overridden accordingly. Specifying GATEWAY_SCHEME_PREFIX_ATTR in the route configuration can also influence the final scheme.

Netty Routing Filter

If the URL in ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR has an http or https scheme, the Netty routing filter uses Netty's HttpClient to forward the request downstream. The response is stored in ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR. An experimental WebClientHttpRoutingFilter provides the same functionality without Netty.

Netty Write Response Filter

When a Netty HttpClientResponse is present in the exchange, the NettyWriteResponseFilter runs after all other filters, writing the downstream response back to the gateway client. An experimental WebClientWriteResponseFilter offers the same behavior without Netty.

RouteToRequestUrl Filter

If the exchange contains a route object ( GATEWAY_ROUTE_ATTR), the RouteToRequestUrlFilter creates a new request URI based on the route's URI and stores it in ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR. If the original URI contains a scheme prefix such as lb:, the prefix is stripped and saved in GATEWAY_SCHEME_PREFIX_ATTR for later filters.

WebSocket Filter

When the request URL in ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR has a ws or wss scheme, the WebSocket routing filter forwards the request using Spring's WebSocket infrastructure. Adding an lb prefix (e.g., lb:ws://serviceid) enables load‑balancing for WebSocket connections.

spring:
  cloud:
    gateway:
      routes:
      # SockJS route
      - id: websocket_sockjs_route
        uri: http://localhost:3001
        predicates:
        - Path=/websocket/info/**
      # Normal WebSocket route
      - id: websocket_route
        uri: ws://localhost:3001
        predicates:
        - Path=/websocket/**

The above filters constitute the core global filters provided by Spring Cloud Gateway; they are applied to every route.

End of guide.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

javaMicroservicesSpring Cloud GatewayGatewayFilterGlobalFilter
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

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.