SpringBoot实战:全局异常处理ErrorController
一、前言
使用SpringBoot时,如果出现404,405,500这种报错信息时,系统会在页面中展示如下内容系统:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing
this as a fallback.Tue Nov 29 10:48:26 CST 2016 There was an unexpected error (type=Bad
Request, status=400). Required String parameter ‘fileName’ is not
present
如果你是开发的程序员,可能还理解这个页面是什么意思,报什么错;但是对于不了解的用户来说,简直就是摸不着头脑。所以这种信息对于用户来说,是非常不友好的。
对于这种报错信息,我们需要做统一处理,我们根据不同的错误类型,返回给用户不同的返回信息。SpringBoot就提供了一个这样统一处理异常的接口类ErrorController。下面我们简单说明一下如何实现一个自定义的异常处理机制。
二、SpringBoot的默认异常处理
要想实现全局异常处理,需要实现ErrorController,并实现getErrorPath方法。系统默认实现的是BasicErrorController,简单看了一下源代码,如果你在配置文件配置了server.error.path的话,就会使用你配置的异常处理地址,如果没有就会使用你配置的error.path路径地址,如果还是没有,默认使用/error来作为发生异常的处理地址。
BasicErrorController类的实现
- BasicErrorController重写了getErrorPath()方法。返回的路径从errorProperties获取。
public String getErrorPath() {
return this.errorProperties.getPath();
}
- errorProperties的取值逻辑为:如果配置文件中配置了地址,则去配置文件中的地址的,如果没有,默认使用/error来作为发生异常的处理地址。
三、自定义全局异常处理
实现一个自定义的全局异常处理类也是非常简单:
- 需要实现ErrorController接口,并重写getErrorPath()方法,指定异常跳转的url;
- 对类添加@RestController注解,添加异常跳转url的Controller;
- 获取请求响应的类型,针对不同的响应错误类型,做不同的逻辑处理。
- 在template目录下存放错误页面的HTML文件。
四、自定义实现
@RestController
public class MainsiteErrorController implements ErrorController {
Logger logger = LoggerFactory.getLogger(MainsiteErrorController.class);
private final String ERROR_PATH ="/error";
/**
* 出现错误,跳转到如下映射中
* @return
*/
@Override
public String getErrorPath() {
return ERROR_PATH;
}
/**
* Web页面错误处理
*/
@RequestMapping(value = ERROR_PATH, produces = {"text/html"})
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
int code = response.getStatus();
if (404 == code) {
return new ModelAndView("error/404");
} else if (403 == code) {
return new ModelAndView("error/403");
} else if (401 == code) {
return new ModelAndView("login");
} else {
return new ModelAndView("error/500");
}
}
@RequestMapping(value =ERROR_PATH)
public R handleError(HttpServletRequest request, HttpServletResponse response) {
int code = response.getStatus();
if (404 == code) {
return R.error(404, "未找到资源");
} else if (403 == code) {
return R.error(403, "没有访问权限");
} else if (401 == code) {
return R.error(401, "登录过期");
} else {
return R.error(500, "服务器错误");
}
}
}