版本:SpringBoot 2.0.4
工具:eclipse 2018-09 (4.9.0)
在项目中一般都会用@ControllerAdvice来进行全局异常捕获机制,但是这种异常处理方式一般是用来处理应用级别的异常,有一些容器级别的错误就处理不了,例如Filter抛出异常,使用@ControllerAdvice定义的全局异常处理机制就无法处理,如果我们需要更加灵活的对ERROR视图和数据进行处理,我们只需要提供自己的ErrorController即可。提供自己的ErrorController有两种方式,一种是实现ErrorController接口,另一种是直接继承BasicErrorController,由于接口只提供一个待实现的方法,而BasicErrorController已实现了很多功能,这里选择继承来实现自己的ErrorController。
具体定义如下:
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorViewResolver;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.ModelAndView;
/**
*
* @ClassName: MyErrorController
* @Description 自定义MyErrorController继承BasicErrorController并添加@Controller注解,把MyErrorController注册到mvc容器中
* @important 当全局异常处理类配置时,仍以此配置为准,异常顺序为cn.junengxiong.config.exception.CustomExceptionHandler捕获后仍被发送到此类中处理
* @version
* @author JH
* @date 2019年4月26日 上午9:12:01
*/
@Controller
public class MyErrorController extends BasicErrorController {
//添加构造方法,因为在创建BasicErrorController实例需要传递参数,使用@Autowired注入所需参数
@Autowired
public MyErrorController(ErrorAttributes errorAttributes, ServerProperties serverProperties,
List<ErrorViewResolver> errorViewResolvers) {
super(errorAttributes, serverProperties.getError(), errorViewResolvers);
}
//重定义网页请求时处理,直接浏览器访问
@Override
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
HttpStatus status = getStatus(request);
Map<String, Object> model = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.TEXT_HTML));
model.put("custommsg", "出错啦!");
ModelAndView mav = new ModelAndView("myErrorPage", model, status);
return mav;
}
//重定义接口请求时处理,postman
@Override
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
Map<String, Object> body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.TEXT_HTML));
body.put("custommsg", "出错啦!");
HttpStatus status = getStatus(request);
return new ResponseEntity<>(body, status);
}
}
- 在maven中引入thymeleaf依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
- 最后在resources/templates下创建myErrorPage.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.html.org">
<head>
<meta charset="UTF-8">
<title>myErrorPage</title>
</head>
<body>
<table border="1">
<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>
-
访问一个错误接口时
postman返回数据
最后需要说明如果同时使用@ControllerAdvice定义了全局异常处理机制,系统会先进入@ControllerAdvice的类,在进入本文配置的处理器,但是即使你在@ControllerAdvice中返回某个页面,也会进入此处理器中,具体返回的参数,跳转的页面仍然以本文的为主!
参考书籍《Spring Boot+Vue 全栈开发实战》