SpringBoot Web项目中对于view的默认错误信息页如下:
并不十分友好,因此需要对异常进行自定义处理,步骤如下:
@ControllerAdvice
Bean。并分别为各异常类制定处理方式。为简单起见,本处仅对Exception(500错误)和NoHandlerFoundException(即404错误)进行处理代码如下:
/*STEP 1 : 声明@ControllerAdvice Bean*/
@ControllerAdvice
public class ErrorView {
@ExceptionHandler(value=Exception.class)
public ModelAndView defaultErrorHandler(HttpServletRequest request, Exception e) throws Exception {
ModelAndView view = new ModelAndView();
view.addObject("ERRORCODE", 500);
view.addObject("ERRORMSG", e.getMessage());
view.addObject("URL", request.getRequestURL());
view.setViewName("error");
return view;
}
@ExceptionHandler(value=NoHandlerFoundException.class)
public ModelAndView pageNoFoundHandler(HttpServletRequest request, Exception e) throws Exception {
ModelAndView view = new ModelAndView();
view.addObject("ERRORCODE", 404);
view.addObject("ERRORMSG", "页面未找到");
view.addObject("URL", request.getRequestURL());
view.setViewName("error");
return view;
}
}
/*STEP - 2 : 设置DispatcherServlet的404异常抛出*/
@EnableScheduling
@SpringBootApplication
public class WebProxy {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(WebProxy.class, args);
// 自定义处理404异常
DispatcherServlet servlet = (DispatcherServlet) ctx.getBean("dispatcherServlet");
servlet.setThrowExceptionIfNoHandlerFound(true);
}
}
在此基础上,制作一个异常页面error.html即可。代码如下(此处借助thymeleaf模板引擎):
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>ERRORtitle>
<div th:include="layout/common :: header">div>
<div th:include="layout/common :: lib">div>
head>
<body>
<header class="header">
<h1>
<a href="#" class="sel-station">错误页面a>
h1>
header>
<div class="content" id="app">
<div class="media"><img th:src="@{/static/images/ico18.png}" width="100%" />div>
<div class="lobby-place">
<section class="item">
<p th:text="'code:'+${ERRORCODE}">ERRORCODEp>
<p th:text="'url:'+${URL}">
URL
p>
<P th:text="'msg:'+${ERRORMSG}">
ERRORMSG
P>
<a class="btn btn-block btn-primary" th:href="@{/view/index}">回首页a>
section>
div>
div>
body>
html>
在增加通用处理前,首先先定义所有API的规范化数据结构。基本信息应包括:状态码statusCode, 状态信息statusMsg,数据data。代码如下:
public class ResultBean {
private int statusCode;
private String statusMsg;
private Object data;
/*getter setter 省略*/
}
定义statusCode == 0 为成功,则从data中获取数据,否则失败,从statusMsg中获取错误信息。
同时,对于请求url地址统一定位于/api/
之下,这样既可通过url判断该请求属于视图还是API接口。
将返回的ModelAndView 改为Object,同时加上@ResponseBody
修改后的@ControllerAdvice
如下
@ControllerAdvice
public class ErrorView {
@ResponseBody
@ExceptionHandler(value=Exception.class)
public Object defaultErrorHandler(HttpServletRequest request, Exception e) throws Exception {
if (!returnJson(request)) {
ModelAndView view = new ModelAndView();
view.addObject("ERRORCODE", 500);
view.addObject("ERRORMSG", e.getMessage());
view.addObject("URL", request.getRequestURL());
view.setViewName("error");
return view;
} else {
System.out.println("is json");
ResultBean bean = new ResultBean();
bean.setReturnCode(-1);
bean.setReturnMsg("[api异常]" + e.getMessage());
return bean;
}
}
@ResponseBody
@ExceptionHandler(value=NoHandlerFoundException.class)
public Object pageNoFoundHandler(HttpServletRequest request, Exception e) throws Exception {
if (!returnJson(request)) {
ModelAndView view = new ModelAndView();
view.addObject("ERRORCODE", 404);
view.addObject("ERRORMSG", "页面未找到");
view.addObject("URL", request.getRequestURL());
view.setViewName("error");
return view;
} else {
System.out.println("is json");
ResultBean bean = new ResultBean();
bean.setReturnCode(-1);
bean.setReturnMsg("地址未找到");
return bean;
}
}
private boolean returnJson(HttpServletRequest request){
System.out.println(request.getRequestURI());
return request.getRequestURI().contains("/api/");
}
}