Spring Boot异常处理
1 Spring Boot默认异常提示
在Spring Boot应用执行过程中难免会出现各种错误,默认情况下,只要出现异常,就会跳转到Spring Boot默认错误提示页面,如下:
为了给用户更好的体验,我们可以使用以下四种手段来优化异常捕获的情况。
2 自定义error的错误页面
刚才我们已经知道SpringBoot应用默认已经提供一套错误处理机制:就是把所有后台错误统一交给error请求,然后跳转到了本身自己的错误提示页面。这时,我们重新建立了一个新的error.html,该页面必须放在resources的templates目录下,如下:
error.html内容如下:
<!DOCTYPE html>
<html>
<head>
<title th:text="${title}"></title>
</head>
<body>
<div >
<div>
<div>
<p><span class="code" th:text="${status}"></span>非常抱歉,页面出现错误</p>
<a href="/" class="btn-back common-button">返回首页</a>
<div >
<div th:text="${#dates.format(timestamp,'yyyy-MM-dd HH:mm:ss')}"></div>
<div th:text="${messages}"></div>
<div th:text="${error}"></div>
</div>
</div>
</div>
</div>
</body>
上面的页面用到了Thymeleaf,所以项目中需要导入Thymeleaf的依赖
<!-- 导入thymeleaf坐标 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
这样,只要应用一出错就会跳转到error.html页面:
源码下载:https://pan.baidu.com/s/1wT-UrAb-DwFfctu37FArwg
3 @ExceptionHandler注解
3.1 @ExceptionHandler简介
@ExceptionHandler源码
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExceptionHandler {
Class<? extends Throwable>[] value() default {};
}
从源码中可以看出,@ExceptionHandler 注解只能作用为对象的方法上,并且在运行时有效,value() 可以指定异常类。由该注解注释的方法可以具有灵活的输入参数。
3.2 具体代码示例
package com.yiidian.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
/**
* 控制器
* 一点教程网 - www.yiidian.com
*/
@Controller
public class HelloController {
@RequestMapping("/hello1")
@ResponseBody
public String hello1(){
//模拟java.lang.ArithmeticException异常
int i = 10/0;
return "欢迎来到一点教程网";
}
@RequestMapping("/hello2")
@ResponseBody
public String hello2(){
//模拟java.lang.NullPointerException异常
String name=null;
name.trim();
return "欢迎来到一点教程网";
}
// 处理java.lang.ArithmeticException
@ExceptionHandler(value = { java.lang.ArithmeticException.class })
@ResponseBody
public String handlerArithmeticException(Exception e) { // e:该对象包含错误信息
return "数学运算错误:"+e.getMessage();
}
// 处理java.lang.NullPointerException
@ExceptionHandler(value = { java.lang.NullPointerException.class })
@ResponseBody
public String handlerNullPointerException(Exception e) { // e:该对象包含错误信息
return "空指针错误:"+e.getMessage();
}
}
3.3 运行效果
源码下载:https://pan.baidu.com/s/1ztcuBj9n-l8EC42yxCp55w
4 @ControllerAdvice注解
刚才的@ExceptionHandler注解是用在控制器类里面的,这样每个控制器都需要定义相关方法,比较繁琐。这时可以使用@ControllerAdvice来抽取所有共同的@ExceptionHandler方法,从而简化异常方法的定义。
代码如下:
package com.yiidian.controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* 自定义全局异常处理类
* 一点教程网 - www.yiidian.com
*/
@ControllerAdvice
public class GlobalExceptionHandler {
// 处理java.lang.ArithmeticException
@ExceptionHandler(value = { java.lang.ArithmeticException.class })
@ResponseBody
public String handlerArithmeticException(Exception e) { // e:该对象包含错误信息
return "数学运算错误:"+e.getMessage();
}
// 处理java.lang.NullPointerException
@ExceptionHandler(value = { java.lang.NullPointerException.class })
@ResponseBody
public String handlerNullPointerException(Exception e) { // e:该对象包含错误信息
return "空指针错误:"+e.getMessage();
}
}
执行效果和第二种方案是一样的!
源码下载:https://pan.baidu.com/s/1h8RukAS9CyritQ1Ag-W4jw
5 HandlerExceptionResovler
5.1 定义全局异常类
package com.yiidian.controller;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 自定义异常处理类
* 一点教程网 - www.yiidian.com
*/
@Configuration
public class MyHandlerExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2,
Exception e) {
ModelAndView mv = new ModelAndView();
//判断不同异常类型,做不同处理
if(e instanceof ArithmeticException){
mv.setViewName("error1");
}
if(e instanceof NullPointerException){
mv.setViewName("error2");
}
mv.addObject("error", e.toString());
return mv;
}
}
5.2 建立error页面
内容如下:
error1.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>自定义错误页面</title>
</head>
<body>
<h3>错误页面-ArithmeticException</h3>
<div th:text="${exception}"></div>
</body>
</html>
error2.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>自定义错误页面</title>
</head>
<body>
<h3>错误页面-NullPointerException</h3>
<div th:text="${exception}"></div>
</body>
</html>
5.3 运行测试
热门文章
优秀文章