目的与原理:

  处理异常时,若我们想根据实际情况返回不同的页面,@ControllerAdvice与@ExceptionHandler,一般用于处理应用级别的异常,一些容器级别的错误就处理不了,例如Filter中抛出异常,SpringBoot对于错误会有一个默认页面给用户显示出来,现在我们想显示自己的页面。

  SpringBoot在返回错误信息时不一定返回HTML页面,而是根据实际情况返回HTML或者一段JSON,我们可以将这二者自己定制。

  SpringBoot中的错误默认是由BasicErrorController类来处理的,这个类核心方法有两个:

@Controller
public class MyErrorController extends BasicErrorController {
@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 modelAndView = new ModelAndView("myErrorPage", model, status);
return modelAndView;
}
@Override
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
Map<String, Object> body = getErrorAttributes(request,
isIncludeStackTrace(request, MediaType.ALL));
body.put("custommsg", "出错啦!");
HttpStatus status = getStatus(request);
return new ResponseEntity<>(body, status);
}
}
  errorHtml方法用来返回错误HTML页面,error用来返回错误json,这两个究竟返回哪个,看请求头Accept参数。首先看返回HTML页面的errorHTML方法,通过调用resolveErrorView方法来获取一个ModelAndView。而resloveErrorView方法的调用最终会来到DefaultErrorViewResolver类中,这个类是SpringBoot中默认的错误信息视图解析器。

  从DefaultErrorViewResolver类的部分源码中看到,SpringBoot默认是在error目录下查找4xx,5xx的文件作为错误视图,当找不到会回到errorHtml方法中,然后使用error作为默认的错误页面视图名,如果没有名字是error的页面,就会以默认的错误页面显示。

1.简单配置:

controller:

  

  如果我们只是简单使用,直接在/static/error/下创建4xx.html,5xx.html的页面即可,也可以使用响应码直接命名文件若404.html,500.html。

这样只能使用静态HTML页面,无法向用户展示完整的错误信息,使用我们要用模板语言,比如用Thymeleaf模板语言为例,Thymeleaf默认处于classpath:/templates/目录下,如图:

4xx.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org/">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<table border="1">
<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>

此时,有一个优先级问题,如以上,响应码.html文件优先于4xx.html文件动态页面高于静态页面(/templates/与/static/下的同名文件,/templates/下先展示)。

2.复杂配置:

  上面的针对HTML页面无法处理JSON定制问题,SpringBoot中支持对Error信息的深度定制:

2.1自定义Error数据

  就是对返回的数据进行自定义,SpringBoot返回的Error信息一共5条,分别是timestamp,status,error,message,path。在BasicErrorController的errorHtml和error方法中都是根据getErrorAttributes方法获取Error信息的。

  该方法最终会调用DefaultErrorAttributes类的getErrorAttributes方法,而DefaultErrorAttribute类是在ErrorMvcAutoConfiguration中默认提供的。

   我们只需要自己提供一个ErrorAttributes即可,DefaultErrorAttributes是ErrorAttributes类的子类,使用我们只需要自己写一个类继承DefaultErrorAttributes即可。

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org/">
<head>
<meta charset="UTF-8">
<title>Title</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>

2.2自定义error视图

  自己提供一个类继承ErrorViewResolver即可

 2.3完全自定义

  前两种都是对BasicErrorController类中的某个环节进行修补,我们可以自己提供一个类实现ErrorController接口。

SpringBoot整合WEB开发--(五)自定义错误页的更多相关文章

  1. springboot整合web开发(整合servlet、filter、listener、访问静态、文件上传)

    整合servlet 1.继承HttpServlet 2.添加@WebServlet注解 @WebServlet(name="FirstServlet",urlPatterns=&q ...

  2. SpringBoot整合WEB开发--(九)整合Servlet,Filter,Listener

    简介: 如果需要整合第三方框架时,可能还是不得不使用Servlet,Filter,Listener,Springboot中也有提供支持. @WebServlet("/my") pu ...

  3. SpringBoot整合WEB开发--(六)CROS支持

    简介: CROS(Cross-Origin Resource Sharing)是由W3C制定的一种跨域资源共享技术标准,其目的为了解决前端的跨域请求,在JavaEE开发中,最常见的前端跨域请求解决方案 ...

  4. SpringBoot整合WEB开发--(二)静态资源访问

    1.默认策略: 静态资源的位置一共5个,开发者可以将静态资源放到其中任意一个,分别是: "classpath:/META-INF/resources/", "classp ...

  5. SpringBoot整合WEB开发--(一)处理JSON返回数据

    1.使用默认的json转换HttpessageConverter Json是目前主流的前后端数据传输方式,SpringMVC中使用消息转化器HttpMessageConverter对JSON的转换提供 ...

  6. SpringBoot整合WEB开发--(十)配置AOP

    简介: SpringBoot框架中对AOP有很好的支持,简单AOP概念: JoinPoint(连接点):类里面可以被增强的方法即为连接点,例如,想修改哪个方法的功能,那么该方法就是一个连接点. Poi ...

  7. SpringBoot整合WEB开发--(八)启动任务系统

    简介: 有一些特殊的任务需要在系统启动时执行,例如配置文件的加载,数据库初始化等操作,如果没有使用SpringBoot,这些问题可以在Listener中解决.SpringBoot提供了两种解决方案:C ...

  8. SpringBoot整合WEB开发--(三)文件上传

    文件上传: Java中文件上传一共涉及到两个组件,CommonsMultipartResolver和StandardServletMultipartResolver,其中CommonsMultipar ...

  9. SpringBoot整合WEB开发--(七)注册拦截器

    1.创建一个拦截器类实现HandlerInterceptor接口,重写其中的3个方法,这拦截器中方法的执行顺序为:preHandle--Controller--postHandle--afterCom ...

随机推荐

  1. NB-Iot和GPRS信号通信模式的对比

    NB-Iot和GPRS信号通信模式的对比

  2. Eclipse安装WebJavaEE插件、Eclipse编写HTML代码(综合问题统一记录)

    1 Eclipse没有Web插件和JavaEE插件咋整 1.1 在Eclipse中菜单help选项中选择install new software选项 1.2 在work with 栏中输入 http: ...

  3. layui导出表格设置常用函数

    1.设置导出单元格为数字格式 字段名: function (value, line, data) { return { v: value, t: 'n' } }

  4. elementui_day02

    Elementui_day02 1. maven多模块搭建 1.1 搭建多模块的好处 1. 方便维护(代码增加,拆分越细,越好维护) 2. 有些公共的内容(BaseDomain.BaseService ...

  5. .net core 3.0一个记录request和respose的中间件

    参考资料 https://www.cnblogs.com/wybin6412/p/10944077.html RequestResponseLog.cs using System; using Sys ...

  6. Java 8 Stream Api 中的 peek 操作

    1. 前言 我在Java8 Stream API 详细使用指南[1] 中讲述了 [Java 8 Stream API]( "Java 8 Stream API") 中 map 操作 ...

  7. c#中for与foreach的使用

    for循环示例: static void Main(string[] args) { string[] s = new string[] { "a,b,c,d,e,f,g" }; ...

  8. python 访问sql server数据库

    访问数据库 cnxn = pyodbc.connect("Driver={SQL Server};Server=localhost;Database=用户名;uid=sa;pwd=密码&qu ...

  9. ECMAScript基本对象——Global全局对象

    特点: 全局对象,这个Global中封装的方法不需要对象就可以直接调用.直接写  方法名():就可以调用 url编码:浏览器自动转换谷歌浏览器:wd=淘宝IE浏览器:wd=%E6%B7%98%E5%A ...

  10. canvas手势解锁源码

    先放图 demo.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...