programing

Spring Boot에서 Web Client Mono를 사용하여 API 응답 오류 메시지 가져오기

elecom 2023. 4. 3. 21:16
반응형

Spring Boot에서 Web Client Mono를 사용하여 API 응답 오류 메시지 가져오기

외부 API를 사용하기 위해 webflux Mono(Spring boot 5)를 사용하고 있습니다.API 응답 상태 코드가 200이면 데이터를 잘 얻을 수 있지만 API가 오류를 반환하면 API에서 오류 메시지를 검색할 수 없습니다.spring webclient 오류 핸들러는 항상 다음과 같은 메시지를 표시합니다.

ClientResponse has erroneous status code: 500 Internal Server ErrorPostMan을 사용하면 API는 상태 코드 500의 JSON 응답을 반환합니다.

{
 "error": {
    "statusCode": 500,
    "name": "Error",
    "message":"Failed to add object with ID:900 as the object exists",
    "stack":"some long message"
   }
}

WebClient를 사용한 요청은 다음과 같습니다.

webClient.getWebClient()
            .post()
            .uri("/api/Card")
            .body(BodyInserters.fromObject(cardObject))
            .retrieve()
            .bodyToMono(String.class)
            .doOnSuccess( args -> {
                System.out.println(args.toString());
            })
            .doOnError( e ->{
                e.printStackTrace();
                System.out.println("Some Error Happend :"+e);
            });

API가 상태 코드 500의 오류를 반환할 때 JSON 응답에 어떻게 접근할 수 있습니까?

오류 세부 정보를 가져오는 경우:

WebClient webClient = WebClient.builder()
    .filter(ExchangeFilterFunction.ofResponseProcessor(clientResponse -> {
        if (clientResponse.statusCode().isError()) {
            return clientResponse.bodyToMono(ErrorDetails.class)
                    .flatMap(errorDetails -> Mono.error(new CustomClientException(clientResponse.statusCode(), errorDetails)));
        }
        return Mono.just(clientResponse);
    }))
    .build();

와 함께

class CustomClientException extends WebClientException {
    private final HttpStatus status;
    private final ErrorDetails details;

    CustomClientException(HttpStatus status, ErrorDetails details) {
        super(status.getReasonPhrase());
        this.status = status;
        this.details = details;
    }

    public HttpStatus getStatus() {
        return status;
    }

    public ErrorDetails getDetails() {
        return details;
    }
}

또,ErrorDetails클래스 매핑 오류 본문

요청 단위 변형:

webClient.get()
    .exchange()
    .map(clientResponse -> {
        if (clientResponse.statusCode().isError()) {
            return clientResponse.bodyToMono(ErrorDetails.class)
                    .flatMap(errorDetails -> Mono.error(new CustomClientException(clientResponse.statusCode(), errorDetails)));
        }
        return clientResponse;
    })

@Frishling의 제안대로 아래와 같이 요청을 변경하였습니다.

return webClient.getWebClient()
 .post()
 .uri("/api/Card")
 .body(BodyInserters.fromObject(cardObject))
 .exchange()
 .flatMap(clientResponse -> {
     if (clientResponse.statusCode().is5xxServerError()) {
        clientResponse.body((clientHttpResponse, context) -> {
           return clientHttpResponse.getBody();
        });
     return clientResponse.bodyToMono(String.class);
   }
   else
     return clientResponse.bodyToMono(String.class);
});

또한 1xx에서 5xx까지의 상태 코드가 몇 개 있기 때문에 경우에 따라 오류 처리가 쉬워집니다.

보다.onErrorMap()이 경우 예외적으로 볼 수 있습니다.exchange()의 body()도 참조해야 할 수 있으므로 retrieve를 사용하지 마십시오.

.exchange().flatMap((ClientResponse) response -> ....);

언급URL : https://stackoverflow.com/questions/49485523/get-api-response-error-message-using-web-client-mono-in-spring-boot

반응형