티스토리 뷰
[MSA] Spring Cloud로 개발하는 MS 어플리케이션 ( Gateway Custom Filter) - 6 -
박강균 IT 2022. 4. 8. 10:09- 해당 글은 아래의 글에서 이어 집니다.
https://ggparkitbank.tistory.com/121
저번 시간까지는 Java와 yml을 활용해서 필터를 만드는 작업을 했어요. 하지만 필터를 사용하다보면
원하는 결과를 자유롭게 받고 싶을때가 있을거에요. 그 때 사용하는 게 CustomFilter입니다.
# CustomFilter
CustomFilter를 작성하기 위해서 Class하나 만들어 줄게요.위치는 기존에 만들어둔 apigateway-service서비스에 만들었어요.깔끔하게 만들고 싶으시다면 com.example.agpgatewayservice 아래 filter 패키지를 하나 더 만들면 좋겠지만저는 예제라서 패스했어요 🤔
이제 CustomFilter 작성을 해야해요! 일단 전체 코드를 첨부할게요.
# CustomFilter.java
package com.example.apigatewayservice;
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 CustomFilter extends AbstractGatewayFilterFactory<CustomFilter.Config> {
public CustomFilter(){
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
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 code -> {}", response.getStatusCode());
}));
};
}
public static class Config {
}
}
복붙하시면 문제는 발생안하겠지만, 이해를 안하고 넘어가면 조금 찝찝할테니 제가 이해한 내용을 바탕으로 조금 설명을 덧붙혀 볼게요. 🤪
# Annotation & extends
@Component
@Slf4j
public class CustomFilter extends AbstractGatewayFilterFactory<CustomFilter.Config> {
@Componet 커스텀 필드는 특이하게 Configuration이 아니라 Component네요. 이는 Custom Filter는 직접 등록하는 형식이라 그런 것 같아요. :) 일단 Component로 등록을 해줍니다.!
@Slf4j 다들 한번 씩은 보셨던 Slf4j! 로깅을 해주고 로그 기능을 활용 할 수 있게 도와주는 Annotation 이에요!
CustomFilter라는 클래스 뒤에 상속받는 객체가 엄청 기네요..
AbstractGatewayFilterFactory<CustomFilter.Config>
Custom Filter로 활용하기 위해선 반드시 상속 받아야 해요. 그리고 뒤에 있는 인자로 CustomFilter.Config를 줬는데 만약 작성 중이시면 여기서 오류가 나실 거에요!아무 위치에 아래와 같은 코드를 입력해줘서 오류를 없애줄게요.
public static class Config {
}
그 뒤에는 상속해주는 객체에게 Config.class를 참조할게요 :)
public CustomFilter(){
super(Config.class);
}
다음으로는 이제 실제 Custom Filter를 작성해볼거에요. 아직 까지 클래스가 빨간색 일텐데.
Implement methods를 통해서 Override를 해준 뒤 다음과 같이 작성해주세요!
@Override
public GatewayFilter apply(Config config) {
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 code -> {}", response.getStatusCode());
}));
};
}
return 에서 람다식을 사용할거에요.
exchange.getRequest(); 를통해 요청값을 담아주고 마찬가지로 exchange.getResponse(); 를 통해서 응답 값도 담아줄게요 !
log를 통해서 요청값의 Id값과 응답값의 상태코드를 보내줄거에요! 뭔가 복잡해보이지만, 해당 구조만 기억한다는 느낌으로
사용하면 될 것 같아요 요청은 당연히 PRE filter로 생각해야하고, 응답은 POST filter로 생각하는게 맞겠죠?이어서 yml파일에 CustomFilter를 등록해줍시다!
#application.yml
server:
port: 8000
eureka:
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://localhost:8761/eureka
spring:
application:
name: apigateway-service
cloud:
gateway:
routes:
- id: fisrt-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
하단에 filter를 보시면 - CustomFilter로 추가된게 보이실거에요! 이 작업만 해주시면 끝이에요 :)
정말 정말 마지막으로 Controller에 Get Mapping을 해줄게요 !
#first-service controller
package com.example.firstservice;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/first-service")
public class FirstServiceController {
@GetMapping("/welcome")
public String welcome(){
return "첫번째 서비스에요.";
}
@GetMapping("/message")
public String message(@RequestHeader("first-request") String header ){
System.out.println(header);
return "나는.. 첫번째 메시지 서비스에요.";
}
@GetMapping("/check")
public String check(){
return "Hi, there. This is a message from Second Service";
}
}
해당 글은 아래의 강좌를 참고해서 만들어 졌습니다. 관심 있으신 분들은 꼭 들어보는 걸 추천 드려요 :)
기존에 작성했던 Controller로 다시 접속을 해서 /check 라는 Mapping을 해줄게요.
자 여기까지 따라오셨다면 정말 잘하셨어요!! 그럼 이제 실행을 해볼까요? Apigateway Service와 First Service , Second Service를 실행해 준 뒤에, Post - Man을 통해서 결과를 확인 해볼게요.
문제 없이 잘 출력 되네요! 그럼 한번 API gateway 프로젝트에서 Console을 확인 해볼까요?
request id와 response code가 잘 출력이 됐나요? 잘 출력이 됐다면 천따봉 드리겠습니다.
다음 시간엔 Global Filter에 대해서 정리해보도록 할게요! 감사합니다.
❓ 어떤 강의를 참조하셨나요
🅰️ 인프런에서 아래의 강의를 참조했습니다! 정말 좋은 강의 이니 꼭 한번 들어보시는 걸 추천드려요
'웹 프로그래밍 > MSA 학개론' 카테고리의 다른 글
[MSA] Spring Cloud로 개발하는 MS 어플리케이션 (Load Balancer) - 8 - (0) | 2022.04.08 |
---|---|
[MSA] Spring Cloud로 개발하는 MS 어플리케이션 ( Gateway Global Filter) - 7 - (0) | 2022.04.08 |
[MSA] Spring Cloud로 개발하는 MS 어플리케이션 ( Gateway Filter) - 5 - (0) | 2022.04.07 |
[MSA] Spring Cloud로 개발하는 MS 어플리케이션 ( Gateway Filter) - 4 - (0) | 2022.04.07 |
[MSA] Spring Cloud로 개발하는 MS 어플리케이션 (Gateway)-3- (0) | 2022.04.07 |
- Total
- Today
- Yesterday
- ACTUATOR
- 운동
- MSA
- git
- github
- UserService
- consumer
- Spring + ELK
- Kafka Connect
- zipkin
- MariaDB
- 빅-오
- rabbitmq
- Gateway
- elasticSearch
- 루틴기록
- Feign
- 오늘저녁 삼겹살
- LoadBalancer
- 미래의나에게동기부여
- springcloud
- producer
- 운동일기
- prometheus
- config
- docker
- Logstash to ElasticSearch
- JWT
- kafka
- Logstash 활용
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |