Spring Cloud Filter

Sei Kim·2024년 1월 14일

Spring Cloud

목록 보기
3/4
post-thumbnail

1. Filter 적용


Spring Cloud 에서 적용할 수 있는 필터들을 적용하는데 다양한 필터들을 확인해보도록 하겠습니다.

2. Custom Filter


가장먼저 커스텀으로 작성하여 사용하는 필터입니다.

AbstractGatewayFilterFactoryextends시켜 구현합니다.

@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

3. Global Filter


위에서 커스텀 필터를 작성해보았습니다. 이번에는 전체 적용할 수 있는 필터를 작성하였습니다.
자바 코드는 기존과 다른게 거의 없으며 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

4. Loggin Filter


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
		# ..

Ref


  1. custom, global filter yaml파일이 아닌 자바 소스에 설정하는 방법 문의드립니다. - 인프런

0개의 댓글