728x90

Spring Cloud Gateway - CustomFilter 적용
apigateway-service 프로젝트
CustomFilter.java 생성

CustomFilter를 사용하려면 AbstractGatewayFilterFactory를 상속받아야 한다.
@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(); // exchange로부터 request, response 값을 얻는다
ServerHttpResponse response = exchange.getResponse();
log.info("Custom PRE filter : request id -> {}",request.getId());
// # Custom Post Filter
// post filter를 적용하기 위해서 반환시켜주는 chain에 연결시켜서
return chain.filter(exchange).then(Mono.fromRunnable(() -> { // Mono : spring5에서 추가되었음
log.info("Custom POST filter: response code -> {}", response.getStatusCode());
}));
});
}
public static class Config {
// put the configuration properties
}
}
👀 Mono
Mono객체는 웹플럭스라고 Spring5에서 추가된 기능이다.
웹 서버 동기 방식이 아닌 비동기 방식에서 단일 값을 전달하기 위해 사용한다.
👀 chain 함수
WebFilter 체인을 통해 다음 단계의 필터를 호출하거나, 필터 체인의 끝에 도달하면 실제 요청을 처리하는 핵심 로직으로 넘어 간다.
👀 return chain.filter(exchange).then(Mono.fromRunnable(() -> { ... }));
• chain.filter(exchange) : 현재 필터의 작업을 완료하고 다음 필터로 요청을 전달
• then : 메서드는 비동기 작업을 설정
• Mono.fromRunnable : Runnable을 기반으로 하는 Mono를 생성하여 해당 Mono가 완료되면 실행되는 비동기 작업을 추가
application.yml에 필터 추가
기존에 적용했던 필터는 주석처리 후 - CustomFilter를 적용한다.
서버 종료 후 재시작.
spring:
application:
name: apigateway-service
cloud:
gateway:
routes:
- id: first-service
uri: http://localhost:8081/
predicates:
- Path=/first-service/**
filters:
# - AddRequestHeader=first-request, first-request-header2
# - AddResponseHeader=first-response, first-response-header2
- CustomFilter // ✔ 여기추가
- id: second-service
uri: http://localhost:8082/
predicates:
- Path=/second-service/**
filters:
# - AddRequestHeader=second-request, second-request-header2
# - AddResponseHeader=second-response, second-response-header2
- CustomFilter // ✔ 여기추가
first-service
check 함수 추가
@GetMapping("/check")
public String check() {
return "Hi, there. This is a message from First Service.";
}
FirstServiceController 전체 코드
더보기
@RestController
@RequestMapping("/first-service")
@Slf4j
public class FirstServiceController {
@GetMapping("/welcome")
public String welcome() {
return "Welcome to the First service";
}
@GetMapping("/message")
public String message(@RequestHeader("first-request") String header) {
log.info(header);
return "Hello world in First Service.";
}
@GetMapping("/check") // ✔ 여기 추가
public String check() {
return "Hi, there. This is a message from First Service.";
}
}
second-service
check 함수 추가
@GetMapping("/check")
public String check() {
return "Hi, there. This is a message from Second Service.";
}
SecondServiceController 전체 코드
더보기
@RestController
@RequestMapping("/second-service")
@Slf4j
public class SecondServiceController {
@GetMapping("/welcome")
public String welcome() {
return "welcome to the second service";
}
@GetMapping("/message")
public String message(@RequestHeader("second-request") String header) {
log.info(header);
return "Hello World in Second Service.";
}
@GetMapping("/check") // ✔ 여기 추가
public String check() {
return "Hi, there. This is a message from Second Service.";
}
}
실행 결과
apigateway-service 콘솔을 보면 filter가 적용되어 값이 잘 나온다!

postman에서 서비스를 확인했다. 잘된다!

728x90