无法在春季返回带有异常详细信息的 ResponseEntity

新手上路,请多包涵

我已经创建了一个 Spring Restful 服务和 Spring MVC 应用程序。

Restful 服务 :: Restful 服务返回一个实体,如果它存在于数据库中。如果不存在,则返回 ResponseEntity 对象中的自定义异常信息。

它正在按使用 Postman 测试的预期工作。

 @GetMapping(value = "/validate/{itemId}", produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE })
public ResponseEntity<MyItem> validateItem(@PathVariable Long itemId, @RequestHeader HttpHeaders httpHeaders) {

    MyItem myItem = myitemService.validateMyItem(itemId);
    ResponseEntity<MyItem> responseEntity = null;
    if (myItem == null) {
        throw new ItemNotFoundException("Item Not Found!!!!");
    }
    responseEntity = new ResponseEntity<MyItem>(myItem, headers, HttpStatus.OK);
    return responseEntity;
}

如果请求的实体不存在,则 Restful 服务返回以下内容。

 @ExceptionHandler(ItemNotFoundException.class)
public ResponseEntity<ExceptionResponse> itemNotFEx(WebRequest webRequest, Exception exception) {
    System.out.println("In CREEH::ItemNFE");
    ExceptionResponse exceptionResponse = new ExceptionResponse("Item Not Found Ex!!!", new Date(), webRequest.getDescription(false));
    ResponseEntity<ExceptionResponse> responseEntity = new ResponseEntity<ExceptionResponse>(exceptionResponse, HttpStatus.NOT_FOUND);
    return responseEntity;
}

但是当我使用 RestTemplate 从 spring MVC 应用程序调用上述服务时,它返回一个有效对象(如果存在)。

如果请求的对象不存在,Restful 服务将返回异常信息,但它不会到达调用(spring MVC)应用程序。

Spring MVC 应用程序使用 Rest 模板调用 Restful Web Service

 String url = "http://localhost:8080/ItemServices/items/validate/{itemId}";
ResponseEntity<Object> responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, Object.class, uriParms);
int restCallStateCode = responseEntity.getStatusCodeValue();

原文由 Abdul 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 758
2 个回答

这是预期的行为。 Rest 模板在 http 状态为客户端错误或服务器错误时抛出异常,当 http 状态不是错误状态时返回响应。

您必须提供实现以使用您的错误处理程序,将响应映射到响应实体并抛出异常。

使用 ResponseEntity 字段创建新的错误异常类。

 public class ResponseEntityErrorException extends RuntimeException {
  private ResponseEntity<ErrorResponse> errorResponse;
  public ResponseEntityErrorException(ResponseEntity<ErrorResponse> errorResponse) {
      this.errorResponse = errorResponse;
  }
  public ResponseEntity<ErrorResponse> getErrorResponse() {
      return errorResponse;
  }
}

将错误响应映射回 ResponseEntity 的自定义错误处理程序。

 public class ResponseEntityErrorHandler implements ResponseErrorHandler {

  private List<HttpMessageConverter<?>> messageConverters;

  @Override
  public boolean hasError(ClientHttpResponse response) throws IOException {
    return hasError(response.getStatusCode());
  }

  protected boolean hasError(HttpStatus statusCode) {
    return (statusCode.is4xxClientError() || statusCode.is5xxServerError());
  }

  @Override
  public void handleError(ClientHttpResponse response) throws IOException {
    HttpMessageConverterExtractor<ExceptionResponse> errorMessageExtractor =
      new HttpMessageConverterExtractor(ExceptionResponse.class, messageConverters);
    ExceptionResponse errorObject = errorMessageExtractor.extractData(response);
    throw new ResponseEntityErrorException(ResponseEntity.status(response.getRawStatusCode()).headers(response.getHeaders()).body(errorObject));
  }

  public void setMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
    this.messageConverters = messageConverters;
  }
}

RestTemplate 配置 - 您必须将 RestTemplate 的 errorHandler 设置为 ResponseEntityErrorHandler。

 @Configuration
public class RestTemplateConfiguration {
  @Bean
  public RestTemplate restTemplate() {
      RestTemplate restTemplate = new RestTemplate();
      ResponseEntityErrorHandler errorHandler = new ResponseEntityErrorHandler();
      errorHandler.setMessageConverters(restTemplate.getMessageConverters());
      restTemplate.setErrorHandler(errorHandler);
      return restTemplate;
   }
}

调用方式

@Autowired restTemplate

String url = "http://localhost:8080/ItemServices/items/validate/{itemId}";
try {
    ResponseEntity<Object> responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, Object.class, uriParms);
    int restCallStateCode = responseEntity.getStatusCodeValue();
} catch (ResponseEntityErrorException re) {
    ResponseEntity<ErrorResponse> errorResponse = re.getErrorResponse();
}

原文由 s7vr 发布,翻译遵循 CC BY-SA 4.0 许可协议

尝试在您的异常处理程序上使用 @ResponseBody 注释。例如:

 public @ResponseBody ResponseEntity<ExceptionResponse> itemNotFEx(WebRequest webRequest, Exception exception) {... }

原文由 Otto Touzil 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题