다음과 같이 application.yml파일을 수정하여 필터를 등록할 수 있다.
아래와 같이 각 서비스 컨트롤러에 check메소드 추가
...
@GetMapping("/check")
public String check(){
return "hello customefilter!";
}
...
@Component
@Slf4j
public class CustomFilter extends AbstractGatewayFilterFactory<CustomFilter.Config> {
public static class Config{
// Put the Configuration properties
}
public CustomFilter(){
super(Config.class);
}
@Override
public GatewayFilter apply(CustomFilter.Config config) {
return ((exchange, chain) -> {
// 비동기방식에서는 ServerHttpResponse 객체를 이용한다. 서블릿 X
//Custom Pre Filter
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(()->{ // Mono Type : 비동기동작 시 단일값 전달에 사용되는 객체
log.info("CUSTOM POST FILTER : response status code -> {}",response.getStatusCode());
}));
});
}
}
위와 같이 커스텀필터를 등록해준다.
참고 ] Exchange객체는 ServerRequest,Response를 핸들링할 수 있도록 스프링에 추가된 객체이다.
커스텀필터는 원하는 라우터마다 등록하는 필터라면, 글로벌 필터는 게이트웨이에 적용되는 전역 필터라고 보면된다. 모든 요청이 게이트웨이를 거쳐 전달되기 때문에 글로벌 필터는 Gateway자체에 등록하여 사용하게된다.
package com.example.apiservice.filter;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
@Component
@Slf4j
public class GlobalFilter extends AbstractGatewayFilterFactory<GlobalFilter.Config> {
public GlobalFilter(){
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
return ((exchange, chain) -> {
// 비동기방식에서는 ServerHttpResponse 객체를 이용한다. 서블릿 X
//GlobalFilter
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
log.info("Global Filter base message: {}",config.getBaseMessage());
if(config.isPreLogger()){
log.info("Global Filter Start : request id -> {}",request.getId());
}
return chain.filter(exchange).then(Mono.fromRunnable(()->{ // Mono Type : 비동기동작 시 단일값 전달에 사용되는 객체
if(config.isPostLogger()){
log.info("Global Filter end : response status code -> {}",response.getStatusCode());
}
}));
});
}
@Data
public static class Config{
private String baseMessage;
private boolean preLogger;
private boolean postLogger;
}
}
아래와 같이 gateway하위에 필터를 등록해준다. 이때 config properties를 명시해준다.