728x90
반응형
스프링 부트에서는 Cloud 환경을 위한 Gateway 프레임워크를 제공한다.
mvn repository에 Maven이나 Gradle에 Dependency를 추가할 수 있도록 검색을 제공한다.
Maven Repository: org.springframework.cloud » spring-cloud-starter-gateway
mvnrepository.com
이 글에서는 PRE, POST 필터를 추가하는 방법을 제시한다.
제공되는 Filter의 종류
org.springframework.cloud.gateway에서 기본적으로 제공하는 필터는 아래와 같이 수십 개의 필터를 제공한다.
YML 설정.
spring:
application:
name: apigateway-service
cloud:
gateway:
default-filters:
- name: GlobalFilter
args:
baseMessage: "Spring Cloud GateWay Global Filter"
preLogger: true
postLogger: true
routes:
- id : first-service
uri: lb://MY-FIRST-SERVICE
predicates:
- Path=/first-service/**
filters:
- AddRequestHeader=first-request, first-request-header2
- AddResponseHeader=first-request, first-request-header2
- CustomFilter
- id: second-service
uri: lb://MY-SECOND-SERVICE
predicates:
- Path=/second-service/**
filters:
- RemoveRequestHeader=Cookie
- RewritePath=/second-service/(?<segment>.*), /$\{segment}
- CustomFilter
- name: LoggingFilter
args:
baseMessage: "Hi, there."
preLogger: true
postLogger: true
위 YML은 총 7개의 필터가 등록되어있다.
적용되는 라우팅 | 필터 종류 | 필터 설명 |
모든 라우팅 ( Global ) | GlobalFilter Filter | 스프링 클라우드 gateway에서 제공하지 않는 커스텀 필터로 모든 라우팅에 해당하는 요청에 필터 처리 |
first-service | AddRequestHeader Filter | 요청에 헤더를 추가하는 필터 |
AddResponseHeader Filter | 응답에 헤더를 추가하는 필터 | |
second-service | RemoveRequestHeader FIlter | 요청의 특정 헤더를 제거하는 필터 |
RewritePath Filter | 요청 Path를 재 정의 하는 필터 | |
LoggingFilter Filter | 스프링 클라우드 gateway에서 제공하지 않는 커스텀 필터로 해당 글에서 설명하는 로깅 필터 | |
first-service, second-service |
CustomFilter Filter | first, second 라우팅에 설정한 커스텀 필터 |
위 yml에 설정되어있는 필터만 사용가능한 것이 아니라 더 많은 필터를 설정할 수 있다.
yml에 필터별로 Config를 설정할 수 있는데 Config속성이 있다면 필터를 정의할 때 -name: 과 같이 정의를 해주어야 한다.
Filter
아래는 위에 정의된 필터들의 소스들이다 필터들은 모두 작성방법이 동일하다
추가로, org.springframework.cloud.gateway에서 제공하는 필터들도 동일한 방법대로 정의되어 있으니 한번 참고해보면 좋을 것 같다.
GlobalFilter
package com.example.apigatewayserver.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;
/**
* Class : CustomFilter
* Author : Jun's
* Description : Class Description
* History : [2022-06-10] - Jun's - Class Create
*/
@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 filter 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{
// Put the configuration properties...
private String baseMessage;
private boolean preLogger;
private boolean postLogger;
}
}
CustomFilter
package com.example.apigatewayserver.filter;
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;
/**
* Class : CustomFilter
* Author : Jun's
* Description : Class Description
* History : [2022-06-10] - Jun's - Class Create
*/
@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 Post filter : response id -> {}", response.getStatusCode());
}));
});
}
public static class Config{
// Put the configuration properties...
}
}
LogginFilter
package com.example.apigatewayserver.filter;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.OrderedGatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
/**
* Class : LoggingFilter
* Author : Jun's
* Description : Class Description
* History : [2022-06-10] - Jun's - Class Create
*/
@Component
@Slf4j
public class LoggingFilter extends AbstractGatewayFilterFactory<LoggingFilter.Config> {
public LoggingFilter() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
// Logging Pre Filter
GatewayFilter filter = new OrderedGatewayFilter((exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
log.info("Logging filter baseMessage : {}", config.getBaseMessage());
if(config.isPreLogger())
log.info("Logging PRE filter : request id -> {}", request.getId());
// Custom Post Filter
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
if(config.isPostLogger())
log.info("Logging POST filter : response code -> {}", response.getStatusCode());
}));
}, Ordered.LOWEST_PRECEDENCE);
return filter;
}
@Data
public static class Config{
// Put the configuration properties...
private String baseMessage;
private boolean preLogger;
private boolean postLogger;
}
}
위와 같은 방법으로 JWT 필터를 게이트웨이에 추가할 수도 있고, Log를 작성할 수도 있고 여러 확장이 제공된다.
728x90
반응형
'Java > SpringBoot' 카테고리의 다른 글
스프링부트 validation 어노테이션 정리 메모장 (0) | 2023.12.26 |
---|---|
RESTful API 설계 및 구현 가이드 (0) | 2023.12.08 |
[Spring Boot] Filter (0) | 2022.06.08 |
[SpringBoot] JPA Entity Listener 엔티티 이벤트 리스너 (2) | 2022.04.26 |
[SpringBoot] Exception Handler 예외를 통합관리 하자.!!! (0) | 2022.04.15 |