
Spring Cloud 에서 적용할 수 있는 필터들을 적용하는데 다양한 필터들을 확인해보도록 하겠습니다.
가장먼저 커스텀으로 작성하여 사용하는 필터입니다.
AbstractGatewayFilterFactory를 extends시켜 구현합니다.
@Component
@Slf4j
public class CustomFilter extends AbstractGatewayFilterFactory<CustomFilter.Config> {
public CustomFilter() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
// Custom Pre Filter
return ((exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
log.info("Custom PRE filter : request id -> {}", request.getId());
// Custom Post Filter
return chain.filter(exchange).then(Mono.fromRunnable(() ->
log.info("Custom PRE filter : response id -> {}", response.getStatusCode())));
});
}
public static class Config {
// Put the Configuration properties
}
}
위애서 작성한 필터를 적용하기 위해서 application.yml 파일에서 원하는 게이트웨이에 해당 필터를 등록시켰습니다.
# ...
spring:
application:
name: apigateway-service
cloud:
gateway:
routes:
- id: first-service
uri: http://localhost:8081/
predicates:
- Path=/first-service/**
filters:
- CustomFilter
- id: second-service
uri: http://localhost:8082/
predicates:
- Path=/second-service/**
filters:
- CustomFilter

위에서 커스텀 필터를 작성해보았습니다. 이번에는 전체 적용할 수 있는 필터를 작성하였습니다.
자바 코드는 기존과 다른게 거의 없으며 Config.class에 변수만 추가하였습니다.
@Component
@Slf4j
public class GlobalFilter extends AbstractGatewayFilterFactory<GlobalFilter.Config> {
public GlobalFilter() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
// Custom Pre Filter
return ((exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
log.info("Global PRE baseMessage : {}", config.getBaseMessage());
if (config.isPreLogger()) {
log.info("Global Filter Start: request id -> {}", request.getId());
}
// Custom Post Filter
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
if (config.isPostLogger()) {
log.info("Global Filter End: response code -> {}", response.getStatusCode());
}
}));
});
}
@Data
public static class Config {
private String baseMessage;
private boolean preLogger;
private boolean postLogger;
}
}
yaml파일에 글로벌 필터를 등록시켰습니다.
spring.cloud.gateway.default-filters 에 원하는 필터를 적용시킨 뒤 매개변수도 하나씩 포함시켰습니다.
# ...
spring:
application:
name: apigateway-service
cloud:
gateway:
routes:
# ...
default-filters:
- name: GlobalFilter
args:
baseMessage: Spring Cloud Gateway Global Filter
preLogger: true
postLogger: true

2번인 커스텀 필터와 별 다를게 없는 필터입니다.
하지만 차이점이라면 OrderedGatewayFilter를 사용하여 우선순위를 적용시켰습니다.
예제 코드는 아래에서 확인할 수 있습니다.
// 일종의 커스텀 필터
@Component
@Slf4j
public class LoggingFilter extends AbstractGatewayFilterFactory<LoggingFilter.Config> {
public LoggingFilter() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
return new OrderedGatewayFilter((exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
log.info("Logging PRE baseMessage : {}", config.getBaseMessage());
if (config.isPreLogger()) {
log.info("Logging Filter Start: request id -> {}", request.getId());
}
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
if (config.isPostLogger()) {
log.info("Logging Filter End: response code -> {}", response.getStatusCode());
}
}));
}, Ordered.LOWEST_PRECEDENCE); // Ordered 에 따라 순서를 정할 수 있다.
}
@Data
public static class Config {
private String baseMessage;
private boolean preLogger;
private boolean postLogger;
}
}
별 다를게 없지만 filters에 매개변수를 넣으려면 반드시 - name: 을 작성해야합니다.
# ...
spring:
application:
name: apigateway-service
cloud:
gateway:
routes:
# ...
- id: second-service
uri: http://localhost:8082/
predicates:
- Path=/second-service/**
filters:
# 매개변수를 넣으려면 `name`이 필요하다.
- name: CustomFilter
- name: LoggingFilter
args:
baseMessage: Hi, there
preLogger: true
postLogger: true
# ..
