[Spring Cloud] Custom Filter 생성 및 설정

rockstar·2023년 6월 23일

Spring

목록 보기
10/10

Spring Cloud Custom Filter

exchange를 통해서 Request, Response 가져온 후에 Pre Filter를 적용시키고, 처리가 끝난 후 Post Filter를 추가하여 return을 하는 방식을 사용했다.

public class CustomFilter extends AbstractGatewayFilterFactory<CustomFilter.Config> {
		@Override
		public GatewayFilter apply(Config config) {
			return (exchange, chain) -> {
				ServerHttpRequest request = exchange.getRequest();
				ServerHttpResponse response = exchange.getResponse();
				log.info("Custom Pre Filter: Request URI -> {}", request.getId());

				return chain.filter(exchange).then(Mono.fromRunnable(() -> {
					log.info("Custom Post Filter: Response code -> {}", response.getStatusCode());
				}));
			};
		}

기본 Filter Yaml 파일 적용

아래의 방식은 따로 Custom Filter를 만들지 않고 적용하는 방식이다.

spring:
	cloud:
 		gateway:
        	routes:
              - id: user
                uri: http://localhost:8080/
                predicates:
                  - Path=/users/**
                filters:
                  //request와 request-header는 Key, Value의 형태다.
                  -AddRequestHeader=user-request, user-request-header
                  -AddResponseHeader=user-response, user-response-header
              - id: order
                uri: http://localhost:8082/
                predicates:
                  - Path=/orders/**
                filters:
                  //request와 request-header는 Key, Value의 형태다.
                  -AddRequestHeader=order-request, order-request-header
                  -AddResponseHeader=order-response, order-response-header

Custom Filter Yaml 파일 적용

아래의 방식은 인자 값이 없는 단순한 Custom Filter을 만든 후 적용하는 방식이다.

spring:
	cloud:
 		gateway:
        	routes:
              - id: user
                uri: http://localhost:8080/
                predicates:
                  - Path=/users/**
                filters:
                  - CustomFilter
              - id: order
                uri: http://localhost:8082/
                predicates:
                  - Path=/orders/**
                filters:
                  - CustomFilter

Global Filter 적용

아래처럼 default-filters 속성을 사용해서 커스터마이징한 Filter와 Config의 속성들에 값을 넣어주면 되고, 추가적으로 인자 값이 필요하기 때문에 주입해줘야 한다.

Ordered.HIGHEST_PRECEDENCE 또는 Ordered.LOWEST_PRECEDENCE 키워드는 Filter의 순서를 설정해준다. Ordered.HIGHEST_PRECEDENCE은 먼저, Ordered.LOWEST_PRECEDENCE는 가장 나중에 실행이 된다고 생각하면 됨

@Component
@Slf4j
public class LoggingFilter extends AbstractGatewayFilterFactory<LoggingFilter.Config> {

	public LoggingFilter() {
		super(Config.class);
	}

	@Override
	public GatewayFilter apply(Config config) {
		GatewayFilter filter = new OrderedGatewayFilter((exchange, chain) -> {
			ServerHttpRequest request = exchange.getRequest();
			ServerHttpResponse response = exchange.getResponse();

			log.info("Logging Filter baseMessage = {}", config.getBaseMessage());

			//Pre Filter
			if (config.preLogger) {
				log.info("Pre Filter Request ID = {}", request.getId());
			}

			//Post Filter
			return chain.filter(exchange).then(Mono.fromRunnable(() -> {
				if (config.postLogger) {
					log.info("Post Filter Response Code = {}", response.getStatusCode());
				}
			}));
		},Ordered.HIGHEST_PRECEDENCE);

		return filter;
	}


	//Config 클래스 static인 것에 주의
	@Data
	public static class Config {
    
    	//아래의 속성들은 application.yml에서 주입
		private String baseMessage;
		private boolean preLogger;
		private boolean postLogger;
	}
}
spring:
  application:
    name: api-gateway
    
  cloud:
    gateway:
      default-filters:
        - name: LoggingFilter
          args:
            baseMessage: Logging Filter
            preLogger: true
            postLogger: true
      routes:
        - id: user
          uri: http://localhost:8080/
          predicates:
            - Path=/users/**


eureka:
  instance:
    instance-id: ${spring.cloud.client.hostname}:${spring.application.instance_id:${random.value}}

  client:
    fetch-registry: true
    register-with-eureka: true
    service-url:
      defaultZone: http://localhost:8761/eureka

잘못된 정보는 지적해주시면 감사하겠습니다.

0개의 댓글