【发布时间】:2018-09-06 10:24:26
【问题描述】:
我在 Spring Data Rest Web 应用程序中使用 @RestResource。我想自定义我的RestResource 的 404 错误。
我知道 ControlerAdvice、处理程序...但 它不适用于 RestResource。
我已经尝试了很多东西:
- 使用 bean 或在 application.properties 中将 setThrowExceptionIfNoHandlerFound 设置为 true
- 在 application.properties 中禁用 spring.resources.add-mappings=false
- 在 ControllerAdvice 上添加 basePackages 或 basePackageClass
- 扩展 RepositoryRestExceptionHandler(但我不能覆盖它,因为方法是包私有的)
我目前的源代码是:
@RestResource(path="user")
public interface UserRepository extends Repository<User, Long> {
User findById(Long id);
}
-
@EnableWebMvc
@ControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class ErrorHandlerController extends ResponseEntityExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
ResponseEntity<?> handleNotFound(ResourceNotFoundException ex) {
ApiError apiError = new ApiError(HttpStatus.INTERNAL_SERVER_ERROR, "Internal server error");
return new ResponseEntity<>(apiError, apiError.getHttpStatus());
}
}
编辑 1(我的问题不是重复的):
我也尝试像这样添加一个新的 RestControllerAdviceHandler (但它不起作用):
@RestControllerAdvice
public class RestControllerAdviceHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<String> defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
return new ResponseEntity<>(" test ", HttpStatus.NOT_FOUND);
}
}
编辑2(关于spring框架源码):
在对 spring 源代码进行了更多研究后,我找到了下面的代码。似乎如果找不到实体,则不会引发异常,RestResource 只是返回了一个新的 ResponseEntity>(HttpStatus.NOT_FOUND))。也许真的无法用 RestResource 拦截和自定义 Not Found 错误?
/**
* <code>GET /{repository}/{id}</code> - Returns a single entity.
*
* @param resourceInformation
* @param id
* @return
* @throws HttpRequestMethodNotSupportedException
*/
@RequestMapping(value = BASE_MAPPING + "/{id}", method = RequestMethod.GET)
public ResponseEntity<Resource<?>> getItemResource(RootResourceInformation resourceInformation,
@BackendId Serializable id, final PersistentEntityResourceAssembler assembler, @RequestHeader HttpHeaders headers)
throws HttpRequestMethodNotSupportedException {
return getItemResource(resourceInformation, id).map(it -> {
PersistentEntity<?, ?> entity = resourceInformation.getPersistentEntity();
return resourceStatus.getStatusAndHeaders(headers, it, entity).toResponseEntity(//
() -> assembler.toFullResource(it));
}).orElseGet(() -> new ResponseEntity<Resource<?>>(HttpStatus.NOT_FOUND));
}
【问题讨论】:
-
@chrylis 我尝试将 404 响应空正文转换为结构化的 json 正文。有什么想法吗?
-
@SupunWijerathne 我们有类似的状态,当找不到实体时,我们想告诉实体不存在,因为空白 404 对于所有业务目的可能没有多大意义。有什么建议吗?
-
@shivaspk 没有答案...所以,我找到了一种解决方法...我创建了一个扩展
org.springframework.web.filter.OncePerRequestFilter的组件类,并拦截了正文不以“{ ”。所以所有不是 json 格式的请求。然后,我用 json 替换响应的主体。我结合请求 url 和 statusCode 来查找 errorMessage。它一点也不完美,但它可以工作......希望有帮助。 -
看起来它已被标记为错误并希望在未来得到解决。 jira.spring.io/browse/…
-
@J.Marciano 感谢您提供的信息!你检查你的 ResponseBodyAdvice 是否在 404 上被调用?我不确定。但如果它是正确的,它真的很有趣。我认为 ResponseBodyAdvice 比 OncePerRequestFilter 级别更高。
标签: java spring spring-boot spring-data-rest