Подтвердить что ты не робот

RestTemplate - Обработка заголовков/элементов ответа в исключениях (RestClientException, HttpStatusCodeException)

В моем спокойном веб-сервисе, в случае неправильного кода запроса (5xx) или 4xx, я пишу в ответ пользовательский заголовок "x-app-err-id".

На стороне клиента я использую метод обмена RestTemplate для создания вызова веб-службы RestFul. Все нормально, когда код ответа 2xx.

ResponseEntity<Component> response = restTemplate.exchange(webSvcURL,
    HttpMethod.POST, 
    requestEntity,
    Component.class);

Но если есть исключение (HttpStatusCodeException) из-за того, что это плохой запрос (5xx) или 4xx, в блоке catch HttpStatusCodeException я получаю ответ (см. выше) как null, и поэтому у меня нет доступа к моему пользовательский заголовок, который я установил в своем веб-сервисе. Как получить пользовательские заголовки от ответа в случае исключений в RestTemplate.

Еще один вопрос: я установил объект ошибки (json) в тело ответа в случае ошибки, и я хотел бы знать, как получить доступ к телу ответа, а также в случае исключений в RestTemplate

4b9b3361

Ответ 1

Я, наконец, сделал это с помощью ResponseErrorHandler.

public class CustomResponseErrorHandler implements ResponseErrorHandler {

    private static ILogger logger = Logger.getLogger(CustomResponseErrorHandler.class);

    private ResponseErrorHandler errorHandler = new DefaultResponseErrorHandler();

    public void handleError(ClientHttpResponse response) throws IOException {

        List<String> customHeader = response.getHeaders().get("x-app-err-id");

        String svcErrorMessageID = "";
        if (customHeader != null) {
            svcErrorMessageID = customHeader.get(0);                
        }

        try {           

            errorHandler.handleError(response);

        } catch (RestClientException scx) {         

            throw new CustomException(scx.getMessage(), scx, svcErrorMessageID);
        }
    }

    public boolean hasError(ClientHttpResponse response) throws IOException {
        return errorHandler.hasError(response);
    }
}

И затем используйте этот настраиваемый обработчик ответа для RestTemplate, настроив, как показано ниже.

<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
   <property name="messageConverters">
       <list>
           <ref bean="jsonConverter" />
       </list>
   </property>    
   <property name="errorHandler" ref="customErrorHandler" />
</bean>

<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
   <property name="supportedMediaTypes" value="application/json" />
</bean>

<bean id="customErrorHandler " class="my.package.CustomResponseErrorHandler">
</bean>

Ответ 2

Вам не нужно создавать настраиваемый обработчик ошибок. Вы можете получить тело и заголовки из HttpStatusCodeException, которое будет выбрано.

try {
    ResponseEntity<Component> response = restTemplate.exchange(webSvcURL,
        HttpMethod.POST, 
        requestEntity,
        Component.class);
} catch (HttpStatusCodeException e) {
    List<String> customHeader = e.getResponseHeaders().get("x-app-err-id");
    String svcErrorMessageID = "";
    if (customHeader != null) {
        svcErrorMessageID = customHeader.get(0);                
    }
    throw new CustomException(e.getMessage(), e, svcErrorMessageID);
    // You can get the body too but you will have to deserialize it yourself
    // e.getResponseBodyAsByteArray()
    // e.getResponseBodyAsString()
}