java - Spring Boot @ControllerAdvice 部分工作,不适用于自定义异常

标签 java spring spring-boot exception-handling

在 Spring Boot 1.5.3 中,我的 @ControllerAdvice 注释 ExceptionHandler 遇到了一个特殊情况。它捕获任何异常默认异常,但如果我抛出自定义异常,它不会触发。

异常处理程序:

@ControllerAdvice
public class ResponseEntityExceptionHandler {

@ExceptionHandler({ HttpMessageNotReadableException.class })
protected ResponseEntity<ErrorModel> handleInvalidJson(RuntimeException e, WebRequest request) {
    return new ResponseEntity<ErrorModel>(new ErrorModel().message("Could not parse JSON."), HttpStatus.BAD_REQUEST);
}

@ExceptionHandler({ NumberFormatException.class })
protected ResponseEntity<ErrorModel> handleInvalidRequest(RuntimeException e, WebRequest request) {
    return new ResponseEntity<ErrorModel>(new ErrorModel().message("Invalid request parameter."), HttpStatus.BAD_REQUEST);
}

@ExceptionHandler({ CannotCreateTransactionException.class })
protected ResponseEntity<ErrorModel> handleTransactionCreationException(RuntimeException e, WebRequest request) {
    return new ResponseEntity<ErrorModel>(new ErrorModel().message("Error connecting to the database, please make sure it is still available."), HttpStatus.BAD_REQUEST);
}

@ExceptionHandler({ NotFoundException.class })
protected ResponseEntity<ErrorModel> handleApiException(RuntimeException e, WebRequest request) {
    return new ResponseEntity<ErrorModel>(new ErrorModel().message(e.getMessage()), HttpStatus.NOT_FOUND);
}
}

前 3 个异常都按预期被捕获和处理,但底部异常由默认的 Spring-Boot ExceptionHandler 处理。这是我在 Controller 中抛出的自定义异常:

public ResponseEntity<?> deleteActor(@ApiParam(value = "Used to identify a single actor.", required = true) @PathVariable("actor_id") Integer actorId, @RequestHeader("Accept") String accept) throws Exception {
Actor actor = actorRepository.findOne(actorId);
if (actor == null) {
    throw new NotFoundException(404, "Not found");
}
actorRepository.delete(actorId);
return new ResponseEntity<Void>(HttpStatus.NO_CONTENT);
}

我试过像这样抛出最常见的异常之一:

public ResponseEntity<?> readActor(@ApiParam(value = "Used to identify a single actor.", required = true) @PathVariable("actor_id") Integer actorId, @RequestHeader("Accept") String accept) throws Exception {
    Actor actor = actorRepository.findOne(actorId);
    if (actor == null) {
        throw new NumberFormatException("");
    }
    return new ResponseEntity<Actor>(actor, HttpStatus.OK);
}

这些都得到了很好的处理...

tomcat 日志也显示了这一点:

2017-06-05 11:30:20.080  INFO 9076 --- [           main] .m.m.a.ExceptionHandlerExceptionResolver : Detected @ExceptionHandler methods in responseEntityExceptionHandler

异常:

public class NotFoundException extends ApiException {
private int code;
public NotFoundException (int code, String msg) {
    super(code, msg);
    this.code = code;
}
}

异常继承自这个基类:

public class ApiException extends Exception{
private int code;
public ApiException (int code, String msg) {
    super(msg);
    this.code = code;
}
}

关于自定义异常为何避免被 ExceptionHandler 检测到的任何想法?

如有必要,我很乐意提供更多信息。

最佳答案

对于这种特殊情况,答案是使用 Exception 而不是 RuntimeException,因为 NotFoundException 仅继承自 Exception。

其他值得注意的事情:

  • 要捕获所有异常,可以使用 @ExceptionHandler(Exception.class)

  • 如果为异常使用通用名称,请始终检查您是否导入了正确的名称。

关于java - Spring Boot @ControllerAdvice 部分工作,不适用于自定义异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44366096/

相关文章:

java - 在 groovy 中记录准备好的 sql 查询

java - 从具有 <String, Class> 属性 HashMaps 的 bean 注入(inject)类

java - 在 JAVA API 上使用时 Let's Encrypt 证书不起作用

java - Spring Controller 不响应 https

java - 在运行 Android 的 JavaFx 中显示节点的延迟

java - AS/400 创建日记帐 JT400 (Java)

java - 使用备用入口点使得黑莓应用程序无法卸载

spring - JdbcDaoSupport 是做什么用的?

spring-boot - 找不到类 org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration]

java - 为什么 Spring Integration 故障转移不显示异常