在带有Spring Rest的全局异常处理程序中具有Generic Exception类处理程序是一种好习惯吗?

时间:2018-09-18 18:44:59

标签: java spring spring-boot exception-handling

我参考了几篇文章,以使用@ControllerAdvice为使用spring的rest api项目创建全局异常处理程序。目的是在发生异常的情况下将正确格式的响应发送给客户端。在某些文章中,他们在全局异常处理程序中添加了ThrowableException。 我是否应该用RunTimeException替换它,因为此块是在运行时发生异常?

异常处理程序代码:

@ControllerAdvice
public class GlobalExceptionHandler{

    @ExceptionHandler(NoDataFoundException.class)
    @ResponseStatus(code=HttpStatus.NOT_FOUND)
    public ResponseEntity<ErrorResponse> handle(NoDataFoundException ex){
        ErrorResponse errorResponse = new ErrorResponse(ex.getMessage(), HttpStatus.NOT_FOUND.value());
        ResponseEntity<ErrorResponse> response = new ResponseEntity<ErrorResponse>(errorResponse, HttpStatus.NOT_FOUND);
        return response;
    }
    ..... more methods to handle custom exceptions

    @ExceptionHandler(Exception.class)
    @ResponseStatus(code=HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseEntity<ErrorResponse> handle(Exception ex){
        ErrorResponse errorResponse = new ErrorResponse("Something went wrong", HttpStatus.INTERNAL_SERVER_ERROR.value());
        ResponseEntity<ErrorResponse> response = new ResponseEntity<ErrorResponse>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
        return response;
    }
}

错误响应代码:

public class ErrorResponse {

    private String message;
    private int statusCode;

    public ErrorResponse(String message, int statusCode) {
        super();
        this.message = message;
        this.statusCode = statusCode;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public int getStatusCode() {
        return statusCode;
    }
    public void setStatusCode(int statusCode) {
        this.statusCode = statusCode;
    }
}  

参考:

  1. https://dzone.com/articles/exception-handling-in-spring-boot-rest-web-service
  2. https://github.com/in28minutes/spring-boot-examples/tree/master/spring-boot-2-rest-service-exception-handling

2 个答案:

答案 0 :(得分:1)

  

我应该用RunTimeException替换它,因为该块是   运行时发生异常?

为确保您捕获到的所有引发的异常,以及组件或异常类型比Exception多的异常处理程序都从未处理过,请为Exception使用处理程序。
RuntimeException的处理程序是不够的,因为在运行时还会抛出已检查的异常,并且如果高级组件的方法声明指定了throws Exceptionthrows "any checked exception",则可能会传播已检查的异常,直到客户或此处将应用默认行为的容器。
例如,想象一下这种可能导致这种情况发生的rest控制器方法声明:

@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public ResponseEntity<Foo> getOne(@PathVariable long id) throws Exception {
       // ....           
}

要覆盖此默认的Spring行为,您将要为Exception添加一个处理程序。
当然,这并不意味着只声明Exception的处理程序是一种方法,但是您可能会遇到一些例外,没有特定的处理,因此一般的处理就可以了。

答案 1 :(得分:0)

老实说,对我来说,拥有异常处理程序句柄Exception似乎有点懒。由于Exception被选中,因此您应该负责处理错误或从错误中恢复。如果您无法从错误中恢复,或者您所处的环境阻止您编写允许您优雅恢复的代码,则应将其重新抛出{{1} }来指示问题。

当然,异常处理程序有两个作用:

  • 它们使您能够定义错误响应的外观以及其详细内容的标准。
  • 它们使您能够记录错误,以便您稍后再进行修复。

我强烈建议将已检查的RuntimeException重新抛出为未检查的模式,并在异常处理程序中对其进行处理。作为故障安全的万能工具,您可以为Exception使用通用异常处理程序,以捕获所有未转换的点,并记录发生的情况。

作为开发人员,在没有明确原因的情况下,您应该允许Exception一直传播到顶部,这绝对是