[SPRING] 스프링 MVC - RestTemplate 출시 예외 HTTP 404 일이
SPRING스프링 MVC - RestTemplate 출시 예외 HTTP 404 일이
나는 자원이 발견되지 않을 때 404 오류를 보내 휴식 서비스가있다. 여기 내 컨트롤러의 소스와 HTTP 404 보낼 예외입니다.
@Controller
@RequestMapping("/site")
public class SiteController
{
@Autowired
private IStoreManager storeManager;
@RequestMapping(value = "/stores/{pkStore}", method = RequestMethod.GET, produces = "application/json")
@ResponseBody
public StoreDto getStoreByPk(@PathVariable long pkStore) {
Store s = storeManager.getStore(pkStore);
if (null == s) {
throw new ResourceNotFoundException("no store with pkStore : " + pkStore);
}
return StoreDto.entityToDto(s);
}
}
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException
{
private static final long serialVersionUID = -6252766749487342137L;
public ResourceNotFoundException(String message) {
super(message);
}
}
때이 코드 RestTemplate로 전화를 시도 :
ResponseEntity<StoreDto> r = restTemplate.getForEntity(url, StoreDto.class, m);
System.out.println(r.getStatusCode());
System.out.println(r.getBody());
나는이 예외가 나타납니다
org.springframework.web.client.RestTemplate handleResponseError
ATTENTION: GET request for "http://........./stores/99" resulted in 404 (Introuvable); invoking error handler
org.springframework.web.client.HttpClientErrorException: 404 Introuvable
나는 내 responseEntity 개체를 탐색하고에 statusCode와 함께 몇 가지 일을 할 수있다 생각했다. 그러나 예외 출시하고 내 응용 프로그램 아래로 이동합니다.
예외를 보내하지만 내 ResponseEntity을 채우지 할 restTemplate에 대한 특정 구성이 있습니다.
도움을 주셔서 대단히 감사합니다.
--
루이
해결법
-
==============================
1.지금까지 내가 알고 있어요, 당신은 실제 ResponseEntity을 얻을 수 있지만, 상태 코드와 바디 (있는 경우)를 제외하고 얻을 수 있습니다 :
지금까지 내가 알고 있어요, 당신은 실제 ResponseEntity을 얻을 수 있지만, 상태 코드와 바디 (있는 경우)를 제외하고 얻을 수 있습니다 :
try { ResponseEntity<StoreDto> r = restTemplate.getForEntity(url, StoreDto.class, m); } catch (final HttpClientErrorException e) { System.out.println(e.getStatusCode()); System.out.println(e.getResponseBodyAsString()); }
-
==============================
2.RESTTemplate는 IMO이 분야에서 매우 부족하다. 오류를받은 경우에 당신이 가능하게 응답 본문을 추출 할 수있는 방법에 대해 여기 좋은 블로그 게시물이있다 :
RESTTemplate는 IMO이 분야에서 매우 부족하다. 오류를받은 경우에 당신이 가능하게 응답 본문을 추출 할 수있는 방법에 대해 여기 좋은 블로그 게시물이있다 :
http://springinpractice.com/2013/10/07/handling-json-error-object-responses-with-springs-resttemplate
오늘로서 템플릿 응답 본문을 추출 할 수있는 가능성을 제공하는 뛰어난 JIRA 요청이있다 :
https://jira.spring.io/browse/SPR-10961
쪼그리고 곰의 답변과 문제는 당신이 404 년대에 대처하고자하는 경우 catch 블록 예 : 내부 상태 코드를 심문해야한다는 것입니다
여기에 내가 내 마지막 프로젝트에이 문제를 가지고 방법입니다. 이 더 나은 방법 일 수 있으며, 내 솔루션은 모든위한 responseBody를 추출하지 않습니다.
public class ClientErrorHandler implements ResponseErrorHandler { @Override public void handleError(ClientHttpResponse response) throws IOException { if (response.getStatusCode() == HttpStatus.NOT_FOUND) { throw new ResourceNotFoundException(); } // handle other possibilities, then use the catch all... throw new UnexpectedHttpException(response.getStatusCode()); } @Override public boolean hasError(ClientHttpResponse response) throws IOException { return response.getStatusCode().series() == HttpStatus.Series.CLIENT_ERROR || response.getStatusCode().series() == HttpStatus.Series.SERVER_ERROR; }
ResourceNotFoundException 및 UnexpectedHttpException 내 자신의 체크되지 않은 예외입니다.
다음은 나머지 템플릿을 생성 할 때 :
RestTemplate template = new RestTemplate(); template.setErrorHandler(new ClientErrorHandler());
이제 우리는 요청을 할 때 구성 깔끔한 약간을 얻을 :
try { HttpEntity response = template.exchange("http://localhost:8080/mywebapp/customer/100029", HttpMethod.GET, requestEntity, String.class); System.out.println(response.getBody()); } catch (ResourceNotFoundException e) { System.out.println("Customer not found"); }
-
==============================
3.그것은 2018 년이고 나는 사람들이 "봄"을 말할 때 실제로 적어도 "봄 부팅"을 의미하는 희망 때문에, 나는 덜 먼지 덮인 접근 주어진 답을 확장하고 싶었다.
그것은 2018 년이고 나는 사람들이 "봄"을 말할 때 실제로 적어도 "봄 부팅"을 의미하는 희망 때문에, 나는 덜 먼지 덮인 접근 주어진 답을 확장하고 싶었다.
이전 답변에서 언급 한 모든 올 - 사용자 정의 ResponseErrorHandler를 사용해야합니다. 지금, 그것은을 구성하는 봄 부팅 세계에서 가장 좋은 방법은 이전보다 조금 더 간단합니다. RestTemplateBuilder라는 편리한 클래스가있다. 당신은 자바 문서의 첫 번째 라인을 읽을 경우는 말한다 :
사실은 그냥하는 방법이있다 :
new RestTemplateBuilder().errorHandler(new DefaultResponseErrorHandler()).build();
그 위에, 봄 사람은 오래 전에 기존의 RestTemplate의 단점을 실현하고, 어떻게 테스트에서 특히 고통 스러울 수 있습니다. 그들은 RestTemplate의 래퍼 역할을하는 편리한 클래스, TestRestTemplate을 만들고 빈 구현의 ErrorHandler를 설정 :
private static class NoOpResponseErrorHandler extends DefaultResponseErrorHandler { @Override public void handleError(ClientHttpResponse response) throws IOException { } }
-
==============================
4.당신은 예외를 throw하지 않습니다 자신의 RestTemplate 래퍼를 만들 수 있지만 수신 상태 코드로 응답을 반환 할 수 있습니다. (당신은 또한 몸을 반환 할 수 있지만 그 형태 보증 그만 것, 그래서 몸 아래 코드는 단순히 null이 남아있다.)
당신은 예외를 throw하지 않습니다 자신의 RestTemplate 래퍼를 만들 수 있지만 수신 상태 코드로 응답을 반환 할 수 있습니다. (당신은 또한 몸을 반환 할 수 있지만 그 형태 보증 그만 것, 그래서 몸 아래 코드는 단순히 null이 남아있다.)
/** * A Rest Template that doesn't throw exceptions if a method returns something other than 2xx */ public class GracefulRestTemplate extends RestTemplate { private final RestTemplate restTemplate; public GracefulRestTemplate(RestTemplate restTemplate) { super(restTemplate.getMessageConverters()); this.restTemplate = restTemplate; } @Override public <T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType) throws RestClientException { return withExceptionHandling(() -> restTemplate.getForEntity(url, responseType)); } @Override public <T> ResponseEntity<T> postForEntity(URI url, Object request, Class<T> responseType) throws RestClientException { return withExceptionHandling(() -> restTemplate.postForEntity(url, request, responseType)); } private <T> ResponseEntity<T> withExceptionHandling(Supplier<ResponseEntity<T>> action) { try { return action.get(); } catch (HttpClientErrorException ex) { return new ResponseEntity<>(ex.getStatusCode()); } } }
-
==============================
5.최근 이것에 대한 사용 사례가 있었다. 내 솔루션 :
최근 이것에 대한 사용 사례가 있었다. 내 솔루션 :
public class MyErrorHandler implements ResponseErrorHandler { @Override public boolean hasError(ClientHttpResponse clientHttpResponse) throws IOException { return hasError(clientHttpResponse.getStatusCode()); } @Override public void handleError(ClientHttpResponse clientHttpResponse) throws IOException { HttpStatus statusCode = clientHttpResponse.getStatusCode(); MediaType contentType = clientHttpResponse .getHeaders() .getContentType(); Charset charset = contentType != null ? contentType.getCharset() : null; byte[] body = FileCopyUtils.copyToByteArray(clientHttpResponse.getBody()); switch (statusCode.series()) { case CLIENT_ERROR: throw new HttpClientErrorException(statusCode, clientHttpResponse.getStatusText(), body, charset); case SERVER_ERROR: throw new HttpServerErrorException(statusCode, clientHttpResponse.getStatusText(), body, charset); default: throw new RestClientException("Unknown status code [" + statusCode + "]"); } } private boolean hasError(HttpStatus statusCode) { return (statusCode.series() == HttpStatus.Series.CLIENT_ERROR || statusCode.series() == HttpStatus.Series.SERVER_ERROR); }
from https://stackoverflow.com/questions/16194014/spring-mvc-resttemplate-launch-exception-when-http-404-happens by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 봄을 통해 편안하고 인증 (0) | 2019.10.03 |
---|---|
[SPRING] 중첩 된 객체와 @Jsonview 사용하여 직렬화하는 방법 (0) | 2019.10.03 |
[SPRING] 봄 : 특정 인터페이스 및 유형의 모든 콩을 얻을 (0) | 2019.10.03 |
[SPRING] 봄 데이터 나머지 V.S 패치 LinkableResources을 PUT (0) | 2019.10.03 |
[SPRING] 스프링 MVC 프레임 워크 : PUT 방식에 MultipartResolver (0) | 2019.10.03 |