服务器之家

服务器之家 > 正文

Spring Boot自定义错误视图的方法详解

时间:2020-08-12 10:40     来源/作者:啊,那一个人

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

如果找不到就用默认的白标错误视图,如下图所示:

Spring Boot自定义错误视图的方法详解

因此,为了给用户最佳的使用体验,404等常见错误需要我们自定义页面来处理。以下是几种自定义错误页面的方式。

方式1. 定义静态的错误页面

在 resources 下的 static 目录下,新建 error 目录,在其中新建各种静态错误页面,如 404、500,也可以模糊处理,如4xx、5xx 等,当程序运行出错时,会自动根据错误代码(如500)找到相应的错误页面(如/static/error/500.html),给予展示。

Spring Boot自定义错误视图的方法详解

方式2. 定义动态的错误页面(有采用模板引擎)

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

Spring Boot自定义错误视图的方法详解

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

Spring Boot自定义错误视图的方法详解

  错误信息定制:

  • timestamp:时间戳
  • status:状态码
  • error:错误提示
  • exception:异常对象
  • trace:跟踪流程日志,404状态下无
  • message:异常消息
  • path:请求路径

方式3. 自定义实现错误视图解析,统一错误处理

  如果不想要使用缺省的错误处理视图解析器,想要定制一些自己的东西(比如说:错误引导信息等),按照官方文档的建议我们可以自定义实现错误视图解析接口来处理。
下面就是通过实现错误视图解析接口ErrorViewResolver,将4xx、5xx的错误页面集中在一个自定义视图上:
1)实现 ErrorViewResolver 接口

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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模板)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
<!DOCTYPE html>
 
<html>
<head >
 <link href="/content/public/images/logo-small.png" rel="external nofollow" 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)" rel="external nofollow" >点击查看明细</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)最后效果

Spring Boot自定义错误视图的方法详解

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

总结

到此这篇关于Spring Boot自定义错误视图的方法详解的文章就介绍到这了,更多相关springboot自定义错误视图内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://www.cnblogs.com/anayigeren/p/13479442.html

相关文章

热门资讯

2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
歪歪漫画vip账号共享2020_yy漫画免费账号密码共享
歪歪漫画vip账号共享2020_yy漫画免费账号密码共享 2020-04-07
Intellij idea2020永久破解,亲测可用!!!
Intellij idea2020永久破解,亲测可用!!! 2020-07-29
男生常说24816是什么意思?女生说13579是什么意思?
男生常说24816是什么意思?女生说13579是什么意思? 2019-09-17
沙雕群名称大全2019精选 今年最火的微信群名沙雕有创意
沙雕群名称大全2019精选 今年最火的微信群名沙雕有创意 2019-07-07
返回顶部