Spring Boot是一款轻量级、简单易用、易于上手的Web开发框架,它为我们提供了许多方便,其中之一就是可以非常方便的处理全局异常。在一个Web应用中,无论怎么小心、怎么仔细,都难免会出现一些意外情况,如数据库访问错误、输入非法参数、网络断开、框架异常等等。对于这些异常,Spring Boot提供了几种优雅的方式来处理。
方式一:@ControllerAdvice + @ExceptionHandler
在Spring Boot中,我们可以通过@ControllerAdvice注解结合@ExceptionHandler注解来处理全局异常。具体的做法是,在一个类上添加@ControllerAdvice注解,然后在该类内部编写@ExceptionHandler注解的方法,这些方法对应不同的异常类型,如下面的例子所示。
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public String handleException(HttpServletRequest request, Exception e) {
//TODO:记录异常日志等操作
return "error";//返回一个错误页面
}
@ExceptionHandler(IOException.class)
public String handleIOException(HttpServletRequest request, IOException e) {
//TODO:记录异常日志等操作
return "io_error";//返回一个IO异常页面
}
}
上面的代码中,我们定义了一个全局异常处理类GlobalExceptionHandler,其中有两个方法,分别用来处理Exception和IOException异常。当系统抛出这两种异常时,Spring Boot框架会自动调用对应的方法来处理异常。我们可以在这些方法中编写任意的代码来记录异常日志、发送邮件通知等操作。
值得一提的是,我们可以在这些方法中返回一个View对象,这个View对象代表了我们的错误页面。例如,上面的代码中,当抛出Exception异常时,我们返回一个名为error的View对象,表示返回error.html页面;当抛出IOException异常时,我们返回一个名为io_error的View对象,表示返回io_error.html页面。这样,我们就能够根据不同的异常类型,返回不同的错误页面。
方式二:@ControllerAdvice + @ResponseStatus
除了使用@ExceptionHandler注解外,我们还可以使用@ResponseStatus注解来处理全局异常。它的做法是,我们先定义一个自定义异常类,然后在这个自定义异常类上添加@ResponseStatus注解,并指定我们想要返回的HTTP错误码。然后,在全局异常处理类(即添加了@ControllerAdvice注解的类)中,捕获这个自定义异常,Spring Boot框架会自动返回我们指定的HTTP错误码。
@ResponseStatus(HttpStatus.BAD_REQUEST)
public class MyBadRequestException extends Exception {
}
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MyBadRequestException.class)
public ResponseEntity<String> handleException(HttpServletRequest request, MyBadRequestException e) {
return new ResponseEntity<>("Bad Request", HttpStatus.BAD_REQUEST);
}
}
上面的代码中,我们定义了一个自定义异常类MyBadRequestException,同时指定了它的HTTP错误码为400(即BAD_REQUEST)。然后,在GlobalExceptionHandler类中,捕获这个自定义异常类,并返回一个HTTP状态码为400的ResponseEntity对象,代表了一个“Bad Request”错误响应。
值得一提的是,使用@ResponseStatus注解有一个缺点,就是我们不能返回一个View对象。因此,如果我们需要返回错误页面,建议使用@ExceptionHandler注解。
示例一:捕获自定义异常
下面是一个使用@ExceptionHandler和自定义异常类的示例代码,它演示了如何捕获我们自己抛出的异常,以及如何返回一个错误页面。
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MyException.class)
public String handleException(HttpServletRequest request, MyException e) {
return "error";//返回一个名为error.html的错误页面
}
}
public class MyException extends Exception {
}
上面的代码中,我们定义了一个自定义异常类MyException,并在GlobalExceptionHandler类中添加了一个@ExceptionHandler注解的方法,用来处理MyException异常。当系统抛出MyException异常时,Spring Boot框架会自动调用对应的方法来处理异常,并返回一个名为error.html的错误页面。
示例二:异常统一处理
下面是一个使用@ControllerAdvice和@ExceptionHandler的示例代码,它演示了如何捕获全局异常,并将它们转换为规范的JSON格式返回。
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<Map<String, Object>> handleException(HttpServletRequest request, Exception e) {
Map<String, Object> error = new HashMap<>();
error.put("status", HttpStatus.INTERNAL_SERVER_ERROR.value());
error.put("message", e.getMessage());
return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
上面的代码中,我们定义了一个GlobalExceptionHandler类,并在该类上添加了@ControllerAdvice注解。然后,在这个类中添加了一个@ExceptionHandler注解的方法,用来处理所有的Exception异常。当系统抛出任何一种Exception异常时,Spring Boot框架都会自动调用对应的方法来处理异常,并将它们转换为一个Map对象,并最终通过一个ResponseEntity对象返回。
为了方便演示,上面的代码中只返回了异常的HTTP状态码和异常信息,我们也可以自由地定制我们的返回数据,例如,增加timeStamp、error等信息。这样做的好处在于,我们能够将异常信息转换为规范的JSON格式,并通过任意的手段(例如REST API)返回给调用者。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot如何优雅的处理全局异常 - Python技术站