욜로가 서비스는 두벅스 서버와 욜로가 서버로 분리되어 있다. 두벅스 서버에서는 사용자 관련 기능과 JWT 륿 발급하는 역할을 한다. 욜로가 서버에서는 욜로가 서비스에서 제공하는 러닝크루 기능을 수행한다. 역할을 분리 하였지만 욜로가 서버에서도 두벅스 서버에서 발급한 JWT 를 검증하고, 해당 사용자가 로그인한 사용자인지 알기 위해 Redis 에 접근해야 한다.

하지만 욜로가 서버에서는 Redis 및 사용자 테이블에 대한 관리 없이 역할을 완전히 분리하고 싶어 두벅스 서버에게 API 를 호출하는 방식 으로 구현하였다. 만약 JWT 및 로그인 여부 검증이 필요한 API 인 경우에는 Interceptor 에서 두벅스 서버에게 API 를 호출 후 200 OK 를 응답받으면 기능을 수행한다. 하지만 실제로 구현을 해보니 두벅스 서버에서 예외가 발생하여도 미리 작성해둔 예외 메시지가 보이지 않는 문제가 발생하였다.

DispatcherServlet,java

Untitled

org.springframework.web.client.HttpClientErrorException$Unauthorized: 401 : [no body]

인증과 관련된 기능이므로 두벅스 서버에서는 예외가 발생하면 401 을 응답한다. 즉, 두벅스 서버에게 접근하였고, 로직을 수행했지만 예외가 발생하여 다음과 같은 응답을 받았다고 추측할 수 있다. 하지만 어떤 이유로 예외가 발생하였는지 메시지가 포함되어 있지 않아 알수가 없었다.

Untitled

(상태코드 401 과 403 만 메시지가 없고, 그 외의 경우에는 포함되어 온다..)

401 에러 발생 시 예외 메시지 포함

따라서 RestTemplate 으로 요청을 보냈을 때 예외 메시지도 포함하여 응답을 받아오도록 설정을 추가하였다.

DobugsConnector.java

import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import jakarta.servlet.http.HttpServletRequest;

@Component
public class DobugsConnector implements Connector {

    private final RestTemplate REST_TEMPLATE = new RestTemplate();

    private final String authHost;
    private final String authPath;

    public DobugsConnector(
        @Value("${auth.host}") final String authHost,
        @Value("${auth.path}") final String authPath
    ) {
        this.authHost = authHost;
        this.authPath = authPath;
        config();
    }

    private void config() {
        REST_TEMPLATE.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
    }

		...
}

HttpComponentsClientHttpRequestFactory 내부에서 HttpClient 객체를 사용하는데 이는 Apache HttpComponents 5.1 이상, Spring 6.0 을 요구하므로 의존성도 추가해준다.

Untitled

build.gradle

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'

    ...

    // rest template
    implementation 'org.apache.httpcomponents.client5:httpclient5:5.2.1'
}

Untitled

설정을 추가한 덕분에 예외 메시지가 포함되었다. 하지만 응답 결과로 로직을 수행해야 하는데 결과가 ResponseEntity 에 담기는 것이 아닌 RestTemplate 내부에서 HttpClientErrorException 이 발생하였다. ControllerAdvice 에서 예외를 캐치해도 되지만 더 편리하게 커스텀하기 위해서 RestTemplate 의 설정을 하나 더 추가하였다.

예외 발생 시 ResponseEntity 에 응답 결과 담기

DobugsConnector.java