Home ✨TIL
Post
Cancel

✨TIL



(관련 글)





이전 글과 같은 WebFlux 코드를 완성하고
baseUrl 관련해 .yml 파일로 관리하기 위해 변수에 넣어 주었다.


1
2
3
4
5
	@Value("${url.server1}")
	private String baseUrl1;

	@Value("${url.server2}")
	private String baseUrl2;


그리고 실행을 하니 baseUrl 이 지정한 빌더에 들어가지 않는 문제가 발생하였다.
.yml 에 지정한 값을 불러오지 못한 것으로 보인다.


1
2
        this.webClient1 = webClientBuilder.clientConnector(new ReactorClientHttpConnector(httpClient)).baseUrl(baseUrl1).build();
        this.webClient2 = webClientBuilder.clientConnector(new ReactorClientHttpConnector(httpClient)).baseUrl(baseUrl2).build();


컨피그 파일의 생성자부분에서 실행되고 있는 이 코드는
프로젝트가 시작되기도 전, 디비가 연결되기도 전에 실행되는 것을 로그로 확인하였다.
@Configuration 애플리케이션이 시작될 때 설정 파일로서 작동하여
.yml 파일에서 지정한 변수를 가지고 오기도 전에 이미 baseUrl 설정 부분이 작동이 끝나
baseUrl 이 null 이 들어가는 문제이다.
환경변수나 직접 값을 넣어 실행했을 때는 문제가 없이 잘 작동하였으나 .yml 에 넣었더니 이런문제가 발생하였다.
어쩔 수 없이 또한번 코드를 수정한다.


같은 파일의 생성자 부분이 아닌 api 호출부분에서 직접 baseUrl를 넣어주는 것으로 수정한다.
이 부분은 메소드 실행시 실행되는 부분으로 .yml 설정한 값을 잘 불러오고 있는 것도 로그로 확인하였다.


분리했던 생성자부분의 webClientBuilder 에서 baseUrl를 설정하지 않기로 결정했으니 분리할 필요가 없어졌다.
이부분을 다시 하나로 만들어주고


1
2
3
4
    this.webClient = webClientBuilder
                        .clientConnector(new ReactorClientHttpConnector(httpClient))
                        // .baseUrl(baseUrl) // 해당 코드 제거
                        .build();


baseUrl(baseUrl1).build()
baseUrl(baseUrl2).build()
이런 방식으로 직접 넣어주도록 코드를 수정한다.


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
        return webClient.mutate().baseUrl(baseUrl1).build() // baseUrl 설정 추가
            .post()
            .uri(uriBuilder -> {
                URI uri = uriBuilder.path("/task.do").build();
                log.info("[{}] Sending POST request to URL: {}", "Task-Server-Connection", uri);
                return uri;
            })
            .contentType(MediaType.MULTIPART_FORM_DATA)
            .body(BodyInserters.fromMultipartData(bodyBuilder.build()))  // 멀티파트 데이터를 요청데이터에 추가
            .retrieve()
            .bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() {})
            .onErrorResume(throwable -> {
                // 서버1로 요청시 통신 중 오류가 발생했을 땐 exception 을 던지지 않고, 같은 과정으로 서버2로 요청을 재시도 한다.
                log.error(SERVER1_CONNECTION_ERROR.getErrorCode() + " :: "+ SERVER1_CONNECTION_ERROR.getErrorMsg());
                return webClient.mutate().baseUrl(baseUrl1).build() // baseUrl 설정 추가
                   .post()
                   .uri(uriBuilder -> {
                        URI uri = uriBuilder.path("/task.do").build();
                        log.info("[{}] Sending POST request to URL: {}", "Task-Server-Connection", uri);
                        return uri;
                   })
                  .contentType(MediaType.MULTIPART_FORM_DATA)
                  .body(BodyInserters.fromMultipartData(bodyBuilder.build()))
                  .retrieve()
                  .bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() {})
                  .transform(this::handleServerErrors); // 2server: 서버2로 재요청도 실패했을 경우의 에러 처리 로직
            })
           .doOnSuccess(map -> {handleDoOnSuccess(value, map);}) // 통신 성공 후: 성공시 처리되는 로직
           .doOnError(ApiClient::handleDoOnError) // 통신 성공 후: 통신은 성공했으나 처리중의 오류 처리 로직
           .then();



This post is licensed under CC BY 4.0 by the author.