如何处理Spring Data Rest Resource中的异常?

时间:2018-09-06 10:24:26

标签: java spring spring-boot spring-data-rest

我在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截取和自定义“未找到”错误是真的不可能吗?

/**
     * <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));
    }

1 个答案:

答案 0 :(得分:1)

该问题最终在Spring Data REST即将发布的3.2版中得到了解决。

抛出ResourceNotFoundException异常,现在可以正确地拦截它。 您使用@ControllerAdvice的解决方案将起作用。

在Spring Boot 2.2.0 M2和以下ExceptionHandler上进行了测试:

@ControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CustomRepositoryRestExceptionHandler {

    @ExceptionHandler
    ResponseEntity<?> handleNotFound(ResourceNotFoundException o_O) {
        // Simply re-throw the exception and let the default handling kick in, which will produce a response body.
        throw o_O;
    }
}

正如评论中已经发布的那样,问题是https://jira.spring.io/browse/DATAREST-1143