异常:阻止当前方法或作用域继续执行的问题。虽然java中有异常处理机制,但是要明确一点,决不应该用"正常"的态度来看待异常。绝对一点说异常就是某种意义上的错误,就是问题,它可能会导致程序失败。之所以java要提出异常处理机制,就是要告诉开发人员,你的程序出现了不正常的情况,请注意。
Throwable
类是 Java 语言中所有错误或异常的超类(这就是一切皆可抛的东西)。它有两个子类:Error
和Exception
。
Error
:用于指示合理的应用程序不应该试图捕获的严重问题。这种情况是很大的问题,大到你不能处理了,所以听之任之就行了,你不用管它。比如说VirtualMachineError
:当 Java 虚拟机崩溃或用尽了它继续操作所需的资源时,抛出该错误。好吧,就算这个异常的存在了,那么应该何时,如何处理它呢??交给JVM吧,没有比它更专业的了。
Exception
:它指出了合理的应用程序想要捕获的条件。
Exception
又分为两类:一种是CheckedException
,一种是UncheckedException
。这两种Exception
的区别主要是CheckedException
需要用try...catch...
显示的捕获,而UncheckedException
不需要捕获。
通常UncheckedException
又叫做RuntimeException
。
《effective java》指出:对于可恢复的条件使用被检查的异常(CheckedException
),对于程序错误(言外之意不可恢复,大错已经酿成)使用运行时异常(RuntimeException
)。
我们常见的RuntimeExcepiton
有IllegalArgumentException
、IllegalStateException
、NullPointerException
、IndexOutOfBoundsException
等等。
对于那些CheckedException
就不胜枚举了,我们在编写程序过程中try...catch...
捕捉的异常都是CheckedException
。io包中的IOException
及其子类,这些都是CheckedException
。
三个语句块的执行顺序是try—>catch—>finally
。
注意:在使用try..catch..finally块的时候,注意千万不要在finally块中使用return,因为finally中的return会覆盖已有的返回值。
切忌使用空catch块
在 Java 中你可以自定义异常。编写自己的异常类时需要记住下面的几点。
package pers.h.springbootdemo.exception; /** * @author :h * @description:自定异常处理测试异常 * @date :Created in 2020/2/22 11:26 */ public class TestException extends RuntimeException { /** * Constructs a new runtime exception with {@code null} as its * detail message. The cause is not initialized, and may subsequently be * initialized by a call to {@link #initCause}. */ public TestException(String message) { super(message); } } 复制代码
测试
/** * 测试异常 * * @author :h * @date :Created in 2020/3/1 12:21 */ public class ExceptionMainDemo { public static void main(String[] arg) { throw new TestException("测试自定义异常"); } } 复制代码
结果
@ControllerAdvice
注解拦截controller异常并统一处理。
@ControllerAdvice
是一个特殊的@Component
,用于标识一个类,这个类中被以下三种注解标识的方法:@ExceptionHandler
,@InitBinder
,@ModelAttribute
,将作用于所有的@Controller类的接口上。
@ExceptionHandler
Annotation for handling exceptions in specific handler classes and/or handler methods. 用于在特定处理程序类和/或处理程序方法中处理异常的注释。
将会拦截Controller的TestException
异常
@ControllerAdvice public class MyExceptionHandler { // Annotation for handling exceptions in specific handler classes and/or handler methods. // 转发到系统的错误处理 // @ExceptionHandler(TestException.class) // public String handleException(Exception e, HttpServletRequest request) { // Map<String, Object> map = new HashMap<>(); // /*对异常信息进行处理*/ // //传入我们自己的错误状态码 4xx 5xx // Integer statusCode = (Integer) request // .getAttribute("javax.servlet.error.status_code"); // request.setAttribute("javax.servlet.error.status_code", 400); // map.put("code", "user.notexist"); // map.put("message", "用户出错啦"); // request.setAttribute("ext", map); // // //转发到/error // return "forward:/error"; // } // Annotation for handling exceptions in specific handler classes and/or handler methods. @ExceptionHandler(TestException.class) @ResponseBody public Map handleException(Exception e, HttpServletRequest request) { Map<String, Object> map = new HashMap<>(); /*对异常信息进行处理*/ //传入我们自己的错误状态码 4xx 5xx Integer statusCode = (Integer) request .getAttribute("javax.servlet.error.status_code"); map.put("code", statusCode); map.put("message", "自定义异常出错了!"); //转发到/error return map; } } //调用 @RequestMapping({"/errorTest"}) public String errorTest() { throw new TestException("测试自定义异常"); } 复制代码
结果
在templates
文件或static
静态资源目录下创建对应的目录和文件即可,springboot会默认先从templates
目录下寻找,其次在static
目录下寻找,如果还是没有则使用系统默认的。