Spring Boot自定义错误视图
Spring Boot缺省错误视图解析器
Web应用在处理请求的过程中发生错误是非常常见的情况,SpringBoot中为我们实现了一个错误视图解析器(DefaultErrorViewResolver)。它基于一些常见的约定,尝试根据HTTP错误状态码解析出错误处理视图。它会在目录/error下针对提供的HTTP错误状态码搜索模板或者静态资源,比如,给定了HTTP状态码404,它会尝试搜索如下模板或者静态资源:
- /<templates>/error/404.<ext> - 这里<templates>表示所配置的模板所在目录,<ext>表示所用的模板的文件名
- /<static>/error/404.html - 这里<static>表示静态资源文件所在路径、
- /<templates>/error/4xx.<ext>
- /<static>/error/4xx.html
如果找不到就用默认的白标错误视图,如下图所示:

因此,为了给用户最佳的使用体验,404等常见错误需要我们自定义页面来处理。以下是几种自定义错误页面的方式。
方式1. 定义静态的错误页面
在 resources 下的 static 目录下,新建 error 目录,在其中新建各种静态错误页面,如 404、500,也可以模糊处理,如4xx、5xx 等,当程序运行出错时,会自动根据错误代码(如500)找到相应的错误页面(如/static/error/500.html),给予展示。

方式2. 定义动态的错误页面(有采用模板引擎)
在有使用模板的情况下,SpringBoot缺省的错误视图解析器也会在/<templates>/error下搜索错误展示视图。我们可以使用项目中的视图模板引擎在错误页面来定制展示我们的错误消息。
1) 在 resources 下的 templates 目录下,新建 error 目录,在其中新建各种静态错误页面,如 404、500,也可以模糊处理,如4xx、5xx 等(与方式1一致)+

在模板引擎的支持下可以取到错误的一些信息,并定制化显示在页面上,如下(freemarker模板):

错误信息定制:
- timestamp:时间戳
- status:状态码
- error:错误提示
- exception:异常对象
- trace:跟踪流程日志,404状态下无
- message:异常消息
- path:请求路径
方式3. 自定义实现错误视图解析,统一错误处理
如果不想要使用缺省的错误处理视图解析器,想要定制一些自己的东西(比如说:错误引导信息等),按照官方文档的建议我们可以自定义实现错误视图解析接口来处理。
下面就是通过实现错误视图解析接口ErrorViewResolver,将4xx、5xx 的错误页面集中在一个自定义视图上:
1)实现 ErrorViewResolver 接口
package com.hongyang.admin.web; import org.springframework.boot.autoconfigure.web.servlet.error.ErrorViewResolver;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest;
import java.util.Map; /**
* 实现自定义的错误视图解析器
*/
@Component
public class AdminErrorViewResolver implements ErrorViewResolver {
/**
* 实现ErrorViewResolver约定方法,
* 返回统一的错误视图.
* @param request
* @param status
* @param model
* @return
*/
@Override
public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
return new ModelAndView("/error/index", model);
}
}
2)完成错误视图,在templates/error下添加index.ftlh视图(freemarker模板)
<!DOCTYPE html> <html>
<head >
<link href="/content/public/images/logo-small.png" rel="shortcut icon" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>${status}</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<style>
body {
position: fixed;
z-index: 10;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
padding: 0;
margin: 0px;
font-size: 14px;
background: #fff;
word-wrap: break-word;
} p {
padding: 0 15px;
} .btn {
border: 0px;
color: #fff;
cursor: pointer;
text-align: center;
background-color: #ff7a5f\0;
box-shadow: #cccccc 0 2px 15px 0;
-webkit-box-shadow: 0 2px 7px 0 rgba(0,0,0,0.2);
background: radial-gradient(circle at 300% 50%, rgb(255, 195, 114) 50%, rgb(255, 105, 90) 100%);
transition: all .2s ease-out,box-shadow .2s ease-out;
} .btn:hover {
color: #FFFFFF;
transform: scale(1.1);
} .btn:focus {
outline: none;
} .container {
margin: 8% auto;
} .container p {
margin: 35px auto;
text-align: center;
} .container img {
width: 20%;
} .container .font {
color: #848484;
} .container .btn-back {
width: 180px;
height: 35px;
border-radius: 6px;
} #container-info {
display: none;
position: fixed;
z-index: 11;
top: 5%;
left: 0;
right: 0;
margin: 0 auto;
width: 65%;
height: 85%;
overflow: hidden;
border-radius: 4px;
border: 1px solid #f1986e;
background-color: #fff;
box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgb(242, 154, 110);
} #container-info .btn-close {
position: absolute;
right: 5px;
top: 5px;
width: 25px;
height: 25px;
line-height: 25px;
font-size: 22px;
padding: 2px;
border-radius: 50%;
text-align: center;
} #container-info p {
font-size: 12px;
line-height: 20px;
} .show {
display: block !important;
} .cor-r {
color: red;
} @media (max-width: 767px) {
.container img {
width: 50%;
}
#container-info {
width: 85%;
}
} .panel-heading {
height: 32px;
line-height: 32px;
padding: 5px 15px;
}
.panel-body {
height: calc(85vh - 40px);
overflow: auto;
}
.panel-orange .panel-heading {
background-color: #ffa0681f;
color: #ff6f5c;
}
</style>
</head>
<body>
<form id="form1" >
<div class="container">
<p><img src="/content/public/images/error_${status}.png"/></p>
<p class="font">${error},<a onclick="errorDetail(true)" href="javascript: void(0)">点击查看明细</a>!</p>
<p><button type="button" class="btn btn-back" id="btnBack" >返回</button></p>
</div>
<div id="container-info">
<span class="btn btn-close" onclick="errorDetail(false)">×</span>
<div class="panel panel-orange">
<div class="panel-heading">
错误说明
</div>
<div class="panel-body">
<#if path??>
<p><b>请求的URL:</b>${path}</p>
</#if>
<#if message??>
<p><b>异常信息:</b><span class="cor-r">${message}</span></p>
</#if>
<#if trace??>
<p><b>StackTrace:</b><br>${trace}</p>
</#if>
</div>
</div>
</div>
<script type="text/javascript">
window.onload = function () {
var btn = document.getElementById("btnBack");
btn.onclick = function () {
var url = document.referrer;
if (url.indexOf("home/main") > 0) {
window.parent.tabDelete();
return;
}
window.history.back(-1);
}
}
function errorDetail(isShow) {
var con = document.getElementById("container-info");
con.className = isShow ? "show" : ""; // 兼容IE8
}
</script>
</form>
</body>
</html>
3)最后效果

错误页面的展示优先级
1、精确大于模糊
2、动态大于静态

Spring Boot自定义错误视图的更多相关文章
- Spring Boot自定义错误页面,Whitelabel Error Page处理方式
我已经是Spring Framework框架的忠实粉丝.对于企业软件开发者来说它提供了对常见问题的通用解决方案,包括那些你在未来开发中没有意识到的问题.但是,它构建的J2EE项目变得比较臃肿,需要被一 ...
- (后端)Spring Boot自定义错误页面,Whitelabel Error Page处理方式(转)
我已经是Spring Framework框架的忠实粉丝.对于企业软件开发者来说它提供了对常见问题的通用解决方案,包括那些你在未来开发中没有意识到的问题.但是,它构建的J2EE项目变得比较臃肿,需要被一 ...
- spring boot 自定义视图路径
boot 自定义访问视图路径 . 配置文件 目录结构 启动类: html页面 访问: 覆盖boot默认路径引用. 如果没有重新配置,则在pom引用模板. 修改配置文件. 注意一定要编译工程
- Spring Boot自定义配置与加载
Spring Boot自定义配置与加载 application.properties主要用来配置数据库连接.日志相关配置等.除了这些配置内容之外,还可以自定义一些配置项,如: my.config.ms ...
- Spring Boot 2.X(四):Spring Boot 自定义 Web MVC 配置
0.准备 Spring Boot 不仅提供了相当简单使用的自动配置功能,而且开放了非常自由灵活的配置类.Spring MVC 为我们提供了 WebMvcConfigurationSupport 类和一 ...
- Spring Boot 自定义kafka 消费者配置 ContainerFactory最佳实践
Spring Boot 自定义kafka 消费者配置 ContainerFactory最佳实践 本篇博文主要提供一个在 SpringBoot 中自定义 kafka配置的实践,想象这样一个场景:你的系统 ...
- Spring Boot自定义starter必知必会条件
前言 在目前的Spring Boot框架中,不管是Spring Boot官方还是非官方,都提供了非常多的starter系列组件,助力开发者在企业应用中的开发,提升研发人员的工作效率,Spring Bo ...
- spring boot自定义线程池以及异步处理
spring boot自定义线程池以及异步处理@Async:什么是线程池?线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线程池线程都是后台线程.每个线程都使 ...
- Spring Boot自定义Redis缓存配置,保存value格式JSON字符串
Spring Boot自定义Redis缓存,保存格式JSON字符串 部分内容转自 https://blog.csdn.net/caojidasabi/article/details/83059642 ...
随机推荐
- 关于git,无论是命令使用还是深入学习,看我总结就够了
周五了,又是划水的一下午,无意中在某号上发现了这样一张图,说的内容很简单,就是我们日常离不开的git,可能因为最近github宕机,网传服务器被盗的新闻把,让我瞬间产生了兴趣,就点进去看一下 大家能看 ...
- 深入浅出Semaphore源码解析
Semaphore通过permits的值来限制线程访问临界资源的总数,属于有限制次数的共享锁,不支持重入. 前提条件 在理解Semaphore时需要具备一些基本的知识: 理解AQS的实现原理 之前有写 ...
- STL源码剖析:配置器
作用:对内存的管理 接口:申请和释放 内容: 几个全局函数 一级配置器 二级配置器 准备知识 POD是什么: Plain Old Data简称POD,表示传统的C语言类型:与POD类型对应的是非POD ...
- iOS倒计时button闪烁
v _button.titleLabel.text = [NSString stringWithFormat:@"%d后重发",t]; [_button setTitle:[NSS ...
- 痞子衡嵌入式:16MB以上NOR Flash使用不当可能会造成软复位后i.MXRT无法正常启动
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT上使用16MB以上NOR Flash软复位无法正常启动问题的分析解决经验. 痞子衡这几天在支持一个i.MXRT1050客户项 ...
- 前端学习(二):head标签
进击のpython ***** 前端学习--head标签 head标签中的相关标签,是看不见摸不着的,仅仅是对应用于网页的一些基础信息(元信息) 前面说的是青春版,完整的head应该是这样的 !< ...
- python基础--14大内置模块(下)
(9)正则表达式和re模块(重点模块) 在我们学习这个模块之前,我们先明确一个关系.模块和实际工作的关系. 1)模块和实际工作时间的关系 1.time模块和时间是什么关系?time模块和时间本身是没有 ...
- 项目总结,彻底掌握NodeJS中如何使用Sequelize
前言 sequelize是什么? sequelize是基于NodeJs的ORM框架,它适用于不同的数据库,如:Postgres.MySQL.SQLite.MariaDB,我们可以通过sequelize ...
- 《谁说菜鸟不会数据分析》高清PDF全彩版|百度网盘免费下载|Python数据分析
<谁说菜鸟不会数据分析>高清PDF全彩版|百度网盘免费下载|Python数据分析 提取码:p7uo 内容简介 <谁说菜鸟不会数据分析(全彩)>内容简介:很多人看到数据分析就望而 ...
- C++中string类型的find 函数
(去膜拜大佬的博客园,结果被自己菜到自闭) find string中find()返回值是字母在母串中的位置(下标记录),如果没有找到,那么会返回一个特别的标记npos. 对其返回的下标position ...