目的与原理:

  处理异常时,若我们想根据实际情况返回不同的页面,@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. C++中字符常量与字符常量不能直接相加

    定义string变量,并进行初始化,如下: string s1 = "Hello"; string s2 = s1 + "World"; string s3 = ...

  2. WebStorm2018破解教程

    话不多说,直接上教程: 1,下载压缩包,并解压缩,下载地址如下: 链接:谁点谁知道提取码:9am8 2,双击压缩包中的WebStorm-2018.2.1.exe文件,进行安装. 3,安装完成之后,将压 ...

  3. P2024 NOI2001 种类冰茶鸡

    展开 题目描述 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A 吃 B,B 吃 C,C 吃 A. 现有 N 个动物,以 1 - N 编号.每个动物都是 A,B,C 中的一种, ...

  4. VMware 安装CentOS8 教程

    安装一台Linux服务器 一.准备工作 1.准备一台服务器 1)下载VMware 百度下载自行安装 2.准备CentOS8 系统盘 1)CentOS8官网 https://www.centos.org ...

  5. EasyUI笔记(三)Window窗口

    本系列只列出一些常用的属性.事件或方法,具体完整知识请查看API文档 Window(窗口) 窗口控件是一个浮动和可拖拽的面板可以用作应用程序窗口.默认情况下,窗口可以移动,调整大小和关闭.它的内容也可 ...

  6. cf1067b

    题意简述:判断所给图是不是一个k递归图 这是一个2递归图 题解:仔细观察发现中心点一定是直径的中点,因此找到直径中点之后进行bfs判断即可,这里注意判断递归层次太大也不符合 const int max ...

  7. Selenium实战(四)——unittest单元测试2(断言方法+discover()多测试用例的执行)

    一.断言方法 方法 检查 版本 assertEqual(a,b) a==b   assertNotEqual(a,b) a!=b   assertTrue(x) bool(x) is True   a ...

  8. PHP0008:PHP基础-数组

  9. css揭秘 一

    当某些值相互依赖是,应该把它们的相互关系用代码表达出来 font-size: 20px; line-height: 1.5; // 行高是字体的1.5倍 当改变某个参数时候,做到只改尽量少的地方,最好 ...

  10. 关于文件中"wb"与"rb"的理解

    “rb”,”wb”这两种方式在操作文件时,直接跳过了系统的编码方式,在windows系统中,用的编码为gbk: ①:with open(“a.txt”,”w”) as f1: F1.write(“aa ...