目录
自定义发生NotFoundException时,跳转至404页面:
一、使用全局异常处理的好处
1、将系统产生的全部异常统一捕获处理。
2、自定义异常需要由全局异常来捕获。
3、JSR303规范的validator参数校验器、参数校验不通过、本身无法使用try.....catch
二、异常处理
2.1、定义错误页面
- 404 代表资源不存在
- 500 服务器错误是
- error 自定义错误信息方式
模拟下服务器错误及找不到页面的场景;
@GetMapping("/") public String toIndex(){ int a = 1/0; return "index"; }
在没有做自定义拦截器之前、是springboot根据错误页面命名的方式拦截了并找到相应的页面。
故若需要将自定义的错误展示出来、具体异常如何处理,就需要自定义一个拦截器:
自定义错误页面
/** * @author Alex */ @ControllerAdvice public class ControllerExceptionHandler { /** * 用日志记录器来记录异常信息 */ private final Logger logger = LoggerFactory.getLogger(this.getClass()); @ExceptionHandler(Exception.class) public ModelAndView exceptionHandler(HttpServletRequest request,Exception e){ // 出现异常的URL、出现异常的信息 {} 作为占位符 logger.error("request URL : {} ,Exception :{}",request.getRequestURL(),e); //需要将信息放在错误页面中、用ModelAndView对象进行传递 ModelAndView mav = new ModelAndView(); mav.addObject("url",request.getRequestURL()); mav.addObject("exception",e); // 日志记录并返回到页面上 mav.setViewName("error/error"); return mav; } }
涉及的两个注解:
@ControllerAdvice 会拦截所标注有@Controller的所有控制类@ExceptionHandler(Exception.class) 说明此方法是可以作为异常处理的方法、只要异常是Exception级别的都可以被此方法拦截
在error页面,接收下:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>error页面</title>
</head>
<body>
<h1 th:text="${url}"></h1>
<h1 th:text="${exception}"></h1>
</body>
</html>
发生异常后:
页面优化:隐藏异常信息
但这些异常信息只要开发者看到就可以了,不需要以文本的形式处理,所以还需要对页面标签进行调整下。
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>error页面</title> </head> <body> <!--<h1 th:text="${url}"></h1>--> <!--<h1 th:text="${exception}"></h1>--> <h1>程序错误</h1> <hr> <div> <div th:utext="'<!--'" th:remove="tag"></div> <div th:utext="'URL:'+${url}" th:remove="tag"></div> <div th:utext="'Exception:'+${exception.message}" th:remove="tag"></div> <ul th:remove="tag"> <li th:each="st:${exception.stackTrace}" th:remove="tag"> <span th:utext="${st}" th:remove="tag"></span> </li> </ul> <div th:utext="'-->'" th:remove="tag"></div> </div> </body> </html>
<和>是转义字符,代表<>大概意思就是将这些信息作为注释、以文本的类型输出在页面。
此时发生错误后的页面:
若是需要查看错误信息,查看网页源码即可、会看到已经将获取到的异常堆栈信息打印在页面了。
自定义发生NotFoundException时,跳转至404页面:
编写一个NotFoundException类,继续 RuntimeException类
@ResponseStatus(HttpStatus.NOT_FOUND) public class NotFoundException extends RuntimeException{ public NotFoundException() { super(); } public NotFoundException(String message) { super(message); } public NotFoundException(String message, Throwable cause) { super(message, cause); } }
@ResponseStatus(HttpStatus.NOT_FOUND)标识的NotFoundException最终会作为资源找不到的状态,最终会返回到404页面。
由于自定义异常类将Controller下所有的异常都拦截了,包括NotFoundException,所有需要在自定义异常类哪儿做一下逻辑判断。
// ResponseStatus.class)!=null 若有指定,则将此异常抛出、不在此处处理 if(AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class)!=null){ throw e; }
测试下:
/** * @author Alex */ @Controller public class IndexController { @GetMapping("/") public String toIndex(){ // int a = 1/0; Integer a =null; if(a==null){ throw new NotFoundException("找不到数据"); } return "index"; } }
结果:
以上便是本篇所有内容