loi*_*oic 27 rest spring resttemplate
我有一个休息服务,当找不到资源时发送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做一些事情.但例外是启动,我的应用程序出现故障.
是否有一个特定的配置,restTemplate不发送异常,但填充我的ResponseEntity.
非常感谢您的帮助.
-
卢瓦克
Squ*_*ear 36
据我所知,您无法获得实际的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());
}
Dic*_*ood 16
REST模板在IMO这个领域非常缺乏.这里有一篇很好的博客文章,介绍如何在收到错误时提取响应正文:
截至今天,有一个杰出的JIRA请求,模板提供了提取响应主体的可能性:
https://jira.spring.io/browse/SPR-10961
Squatting Bear答案的问题在于你必须查询catch块内的状态代码,例如,如果你只想处理404的问题
以下是我在上一个项目中解决这个问题的方法.可能有更好的方法,我的解决方案根本不提取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");
    }
yur*_*s87 10
从2018年开始,我希望当人们说"春天"时,他们实际上至少意味着"春季启动",我想用一种不那么尘埃覆盖的方法来扩展给定的答案.
之前答案中提到的所有内容都是正确的 - 您需要使用自定义ResponseErrorHandler.现在,在Spring Boot世界中,配置它的方式比以前简单一些.有一个方便的类叫RestTemplateBuilder.如果您阅读其java文档的第一行,它会说:
可用于配置和创建RestTemplate的构建器.提供方便的方法来注册转换器,错误处理程序 和UriTemplateHandlers.
它实际上有一个方法:
new RestTemplateBuilder().errorHandler(new DefaultResponseErrorHandler()).build();
最重要的是,Spring的人们RestTemplate很久以前就意识到了传统的缺点,以及在测试中它是如何特别痛苦的.他们创建了一个方便的类,TestRestTemplate它作为包装器RestTemplate并将其errorHandler设置为空实现:
private static class NoOpResponseErrorHandler extends 
       DefaultResponseErrorHandler {
    @Override
    public void handleError(ClientHttpResponse response) throws IOException {
    }
}
您可以创建自己的 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());
        }
    }
}
| 归档时间: | 
 | 
| 查看次数: | 41130 次 | 
| 最近记录: |