@ExceptionHandler
单独使用一般是用在控制器的内部某个方法上,表示捕捉控制器内部抛出的异常
详细的使用方法请参考:lkforce的博客
@ControllerAdvice+@ExceptionHandler
Spring 3.2之后加入了新的@ControllerAdvice注解,可以支持全局的异常处理。
自定义全局异常并打印系统默认日志demo:
第一步:配置文件
设置日志级别和日志保存地址
logging.level.root=info
logging.level.kjl.blog=debug
logging.file.name=log/blog.log
第二步:编写处理异常控制器
@ControllerAdvice控制器增强
@ExceptionHandler(Exception.class)申明捕获异常类
通过新建一个ModelAndView并返回特定的页面,在页面中凸显出想要显示的信息
@ControllerAdvice
public class ControllerExceptionHandler {
private final Logger logger=LoggerFactory.getLogger(this.getClass());
@ExceptionHandler(Exception.class)
public ModelAndView exceptionHandler(HttpServletRequest request, Exception e) throws Exception {
logger.error("Request URL : {}, Exception : {}",request.getRequestURL(),e);
ModelAndView mv=new ModelAndView("error/error");
mv.addObject("url",request.getRequestURL());
mv.addObject("exception",e);
return mv;
}
}
第三步:编写前端展示页面error.html
此处要引入thymeleaf依赖,和对thymeleaf进行配置
//maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
//配置
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.servlet.content-type=text/html
spring.thymeleaf.mode=HTML
在静态资源templates下新建一个error文件夹,在error文件夹下新增error.html页面
编写error页面
xmlns定义命名空间,其中th:text="${属性}"中属性为前面控制器创建的mv中的键入属性
exception.stackTrace为异常的堆栈信息
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>出错啦</h2>
<ul>
<li>url:<span th:text="${url}"></span></li>
<li>e:<span th:text="${exception}"></span></li>
</ul>
<h2>出错信息如下:</h2>
<ul>
<li th:each="st:${exception.stackTrace}">
<span th:text="${st}"></span>
</li>
</ul>
</body>
</html>
编写一个错误指令9/0
@GetMapping("hello")
public String hello(){
int i=9/0;
return "index";
}
页面打印异常
第四步:处理业务异常:比如找不到资源和页面等
1.新建异常NotFoundException继承RuntimeException
设置@ResponseStatus工具类解析自定义异常
@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);
}
}
2.在ControllerExceptionHandler类中exceptionHandler方法中加入以下代码,判断状态是否为空,如果不为空,抛出异常:
if(AnnotationUtils.findAnnotation(e.getClass(),ResponseStatus.class)!=null){
throw e;
}
3.自定义404异常显示信息
通过getErrorAttribute.get("status")来捕获异常状态码,并返回特定的异常信息
//自定义error数据
@Component
public class MyErrorAttribute extends DefaultErrorAttributes {
@Override
public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) {
Map<String,Object> getErrorAttributes=super.getErrorAttributes(webRequest,options);
if((int)getErrorAttributes.get("status")==404){
getErrorAttributes.put("custommsg","您要找的博客找不到啦");
getErrorAttributes.put("message","您访问的了一个错误页面");
}
return getErrorAttributes;
}
@Override
public Throwable getError(WebRequest webRequest) {
return super.getError(webRequest);
}
}
4.编写404页面,输出自定义信息,同样放在templates的error目录下
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<table border="1" bgcolor="#7fffd4">
<tr>
<td>custommsg</td>
<td th:text="${custommsg}"></td>
</tr>
<tr>
<td>timestamp</td>
<td th:text="${timestamp}"></td>
</tr>
<tr>
<td>status</td>
<td th:text="${status}"></td>
</tr>
<tr>
<td>error</td>
<td th:text="${error}"></td>
</tr>
<tr>
<td>message</td>
<td th:text="${message}"></td>
</tr>
<tr>
<td>path</td>
<td th:text="${path}"></td>
</tr>
</table>
</body>
</html>
5.编写测试类
@GetMapping("none")
private String none() {
String blog=null;
if (blog==null) throw new NotFoundException("none发出的请求导致博客不存在");
return "index";
}
6.结果显示
访问none:
访问不存在的类:
水平有限,错误请指正,一起学习,一起进步!