Обработка исключений пружинной опоры
Ниже приведен фрагмент кода, в основном, я пытаюсь распространить исключение, когда код ошибки не 200.
ResponseEntity<Object> response = restTemplate.exchange(url.toString().replace("{version}", version),
HttpMethod.POST, entity, Object.class);
if(response.getStatusCode().value()!= 200){
logger.debug("Encountered Error while Calling API");
throw new ApplicationException();
}
однако в случае 500 ответа от сервера я получаю исключение
org.springframework.web.client.HttpServerErrorException: 500 Internal Server Error
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:94) ~[spring-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
действительно ли мне нужно обернуть метод обмена шаблонами rest в try? Какова же тогда цель кодов?
7 ответов:
вы хотите создать класс, реализующий
ResponseErrorHandlerа затем использовать его экземпляр, чтобы установить обработку ошибок вашего шаблона rest:public class MyErrorHandler implements ResponseErrorHandler { @Override public void handleError(ClientHttpResponse response) throws IOException { // your error handling here } @Override public boolean hasError(ClientHttpResponse response) throws IOException { ... } } [...] public static void main(String args[]) { RestTemplate restTemplate = new RestTemplate(); restTemplate.setErrorHandler(new MyErrorHandler()); }кроме того, Весна имеет класс
DefaultResponseErrorHandler, который вы можете расширить, вместо реализации интерфейса, в случае, если вы только хотите переопределитьhandleErrorметод.public class MyErrorHandler extends DefaultResponseErrorHandler { @Override public void handleError(ClientHttpResponse response) throws IOException { // your error handling here } }С исходный код чтобы иметь представление о том, как Spring обрабатывает ошибки HTTP.
вы должны поймать
HttpStatusCodeExceptionисключения:try { restTemplate.exchange(...); } catch (HttpStatusCodeException exception) { int statusCode = exception.getStatusCode().value(); ... }
Spring умело обрабатывает коды ошибок http как исключения и предполагает, что ваш код обработки исключений имеет контекст для обработки ошибки. Чтобы exchange функционировал так, как вы ожидаете, сделайте следующее:
try { return restTemplate.exchange(url, httpMethod, httpEntity, String.class); } catch(HttpStatusCodeException e) { return ResponseEntity.status(e.getRawStatusCode()).headers(e.getResponseHeaders()) .body(e.getResponseBodyAsString()); }это вернет все ожидаемые результаты от ответа.
другое решение-это то, которое описано здесь в конце этого поста "enlian": http://springinpractice.com/2013/10/07/handling-json-error-object-responses-with-springs-resttemplate
try{ restTemplate.exchange(...) } catch(HttpStatusCodeException e){ String errorpayload = e.getResponseBodyAsString(); //do whatever you want } catch(RestClientException e){ //no response payload, tell the user sth else }
если вы используете пул (http client factory) или механизм балансировки нагрузки (eureka) с вашим
RestTemplate, вы не будете иметь роскошь созданииnew RestTemplateдля каждого класса. Если вы вызываете несколько служб, вы не можете использоватьsetErrorHandlerпотому что если будет использоваться глобально для всех ваших запросов.в этом случае ловить
HttpStatusCodeExceptionкажется, это лучший вариант.единственный вариант у вас есть, чтобы задать несколько
RestTemplateэкземпляров с помощью@Qualifierаннотация.также - но это мой собственный вкус - мне нравится, когда моя обработка ошибок плотно прижимается к моим звонкам.
код обмена ниже:
public <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables) throws RestClientExceptionисключение
RestClientExceptionиHttpClientErrorExceptionиHttpStatusCodeExceptionисключения.так
RestTempleteздесь может возникнутьHttpClientErrorExceptionиHttpStatusCodeExceptionисключения. В exception object вы можете получить точное сообщение об ошибке, используя этот способ:exception.getResponseBodyAsString()вот пример кода:
public Object callToRestService(HttpMethod httpMethod, String url, Object requestObject, Class<?> responseObject) { printLog( "Url : " + url); printLog( "callToRestService Request : " + new GsonBuilder().setPrettyPrinting().create().toJson(requestObject)); try { RestTemplate restTemplate = new RestTemplate(); restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter()); restTemplate.getMessageConverters().add(new StringHttpMessageConverter()); HttpHeaders requestHeaders = new HttpHeaders(); requestHeaders.setContentType(MediaType.APPLICATION_JSON); HttpEntity<Object> entity = new HttpEntity<>(requestObject, requestHeaders); long start = System.currentTimeMillis(); ResponseEntity<?> responseEntity = restTemplate.exchange(url, httpMethod, entity, responseObject); printLog( "callToRestService Status : " + responseEntity.getStatusCodeValue()); printLog( "callToRestService Body : " + new GsonBuilder().setPrettyPrinting().create().toJson(responseEntity.getBody())); long elapsedTime = System.currentTimeMillis() - start; printLog( "callToRestService Execution time: " + elapsedTime + " Milliseconds)"); if (responseEntity.getStatusCodeValue() == 200 && responseEntity.getBody() != null) { return responseEntity.getBody(); } } catch (HttpClientErrorException exception) { printLog( "callToRestService Error :" + exception.getResponseBodyAsString()); //Handle exception here }catch (HttpStatusCodeException exception) { printLog( "callToRestService Error :" + exception.getResponseBodyAsString()); //Handle exception here } return null; }Вот описание кода:
в этом методе вы должны пройти класс запроса и ответа. Этот метод будет автоматически анализировать ответ как запрошенный объект.
прежде всего, вы должны добавить конвертер сообщений.
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter()); restTemplate.getMessageConverters().add(new StringHttpMessageConverter());тогда вы должны добавить
requestHeader. Вот код:HttpHeaders requestHeaders = new HttpHeaders(); requestHeaders.setContentType(MediaType.APPLICATION_JSON); HttpEntity<Object> entity = new HttpEntity<>(requestObject, requestHeaders);наконец, вы должны вызвать метод exchange:
ResponseEntity<?> responseEntity = restTemplate.exchange(url, httpMethod, entity, responseObject);для печати prety я использовал библиотеку Gson. вот Градель:
compile 'com.google.code.gson:gson:2.4'вы можете просто вызвать ниже код, чтобы получить ответ:
ResponseObject response=new RestExample().callToRestService(HttpMethod.POST,"URL_HERE",new RequestObject(),ResponseObject.class);вот полный рабочий код:
import com.google.gson.GsonBuilder; import org.springframework.http.*; import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.HttpStatusCodeException; import org.springframework.web.client.RestTemplate; public class RestExample { public RestExample() { } public Object callToRestService(HttpMethod httpMethod, String url, Object requestObject, Class<?> responseObject) { printLog( "Url : " + url); printLog( "callToRestService Request : " + new GsonBuilder().setPrettyPrinting().create().toJson(requestObject)); try { RestTemplate restTemplate = new RestTemplate(); restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter()); restTemplate.getMessageConverters().add(new StringHttpMessageConverter()); HttpHeaders requestHeaders = new HttpHeaders(); requestHeaders.setContentType(MediaType.APPLICATION_JSON); HttpEntity<Object> entity = new HttpEntity<>(requestObject, requestHeaders); long start = System.currentTimeMillis(); ResponseEntity<?> responseEntity = restTemplate.exchange(url, httpMethod, entity, responseObject); printLog( "callToRestService Status : " + responseEntity.getStatusCodeValue()); printLog( "callToRestService Body : " + new GsonBuilder().setPrettyPrinting().create().toJson(responseEntity.getBody())); long elapsedTime = System.currentTimeMillis() - start; printLog( "callToRestService Execution time: " + elapsedTime + " Milliseconds)"); if (responseEntity.getStatusCodeValue() == 200 && responseEntity.getBody() != null) { return responseEntity.getBody(); } } catch (HttpClientErrorException exception) { printLog( "callToRestService Error :" + exception.getResponseBodyAsString()); //Handle exception here }catch (HttpStatusCodeException exception) { printLog( "callToRestService Error :" + exception.getResponseBodyAsString()); //Handle exception here } return null; } private void printLog(String message){ System.out.println(message); } }спасибо :)
вот мой метод POST с HTTPS, который возвращает тело ответа для любого типа плохих ответов.
public String postHTTPSRequest(String url,String requestJson) { //SSL Context CloseableHttpClient httpClient = HttpClients.custom().setSSLHostnameVerifier(new NoopHostnameVerifier()).build(); HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); requestFactory.setHttpClient(httpClient); //Initiate REST Template RestTemplate restTemplate = new RestTemplate(requestFactory); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); //Send the Request and get the response. HttpEntity<String> entity = new HttpEntity<String>(requestJson,headers); ResponseEntity<String> response; String stringResponse = ""; try { response = restTemplate.postForEntity(url, entity, String.class); stringResponse = response.getBody(); } catch (HttpClientErrorException e) { stringResponse = e.getResponseBodyAsString(); } return stringResponse; }
Comments