SpringBoot中定制异常页面的实现方法

 更新时间:2020年09月10日 12:00:22   作者:Asurplus、  
这篇文章主要介绍了SpringBoot中定制异常页面的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

定制异常页面,可以避免用户产生恐慌心理,使得产品有更好的用户体验。今天来学习在 SpringBoot 中如何定制开发异常页面

一、历史回顾

在 SpringMVC 年代,我们的异常页面一般配置在 web.xml 文件中,如下:

<!-- 配置404页面 -->
<error-page>
   <error-code>404</error-code>
   <location>/error/404.html</location>
 </error-page>

这里我们指定了异常请求状态码 404,然后配置了 404 异常请求的页面地址,这就意味着如果某一个请求发生了 404 异常,则会出现 404.html 界面

二、SpringBoot中配置

1、默认异常页面


这是 SpringBoot 中默认的异常页面,返回的是一堆异常信息和异常状态码,那用户固然是看不懂这些信息的,容易使得用户产生恐慌的心里,从而影响产品的用户体验

2、定制异常页面

SpringBoot 中定制异常页面非常简单,我们需要一个配置文件 ExceptionPageConfig.java

import org.springframework.boot.web.server.ConfigurableWebServerFactory;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;

/**
 * 统一异常页面处理
 *
 * @Author Lizhou
 **/
@Configuration
public class ExceptionPageConfig {

  /**
   * SpringBoot2.0以上版本
   * WebServerFactoryCustomizer代替之前版本的EmbeddedWebServerFactoryCustomizerAutoConfiguration
   *
   * @return
   */
  @Bean
  public WebServerFactoryCustomizer<ConfigurableWebServerFactory> webServerFactoryCustomizer() {
    return (container -> {
      ErrorPage error400Page = new ErrorPage(HttpStatus.BAD_REQUEST, "/400");
      ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/404");
      ErrorPage error500Page = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/500");
      container.addErrorPages(error400Page, error404Page, error500Page);
    });
  }
}

可以看出,这里我们配置了 400、404、500 三种异常页面,然后我们需要编写 API 请求异常页面 SysExceptionController.java

import com.zyxx.common.utils.PasswordUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author lizhou
 * @since 2020-07-15
 **/
@Api(tags = "后台管理端--异常处理")
@Controller
public class SysExceptionController {

  @ApiOperation(value = "请求400页面", notes = "请求400页面")
  @GetMapping("400")
  public String badRequest() {
    return "sys/exception/400";
  }

  @ApiOperation(value = "请求404页面", notes = "请求404页面")
  @GetMapping("404")
  public String notFound() {
    return "sys/exception/404";
  }

  @ApiOperation(value = "请求500页面", notes = "请求500页面")
  @GetMapping("500")
  public String serverError() {
    return "sys/exception/500";
  }
}

API 写好,下面我们就需要开发异常页面的展示信息了,这里贴一张页面吧,404.html

import com.zyxx.common.utils.PasswordUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author lizhou
 * @since 2020-07-15
 **/
@Api(tags = "后台管理端--异常处理")
@Controller
public class SysExceptionController {

  @ApiOperation(value = "请求400页面", notes = "请求400页面")
  @GetMapping("400")
  public String badRequest() {
    return "sys/exception/400";
  }

  @ApiOperation(value = "请求404页面", notes = "请求404页面")
  @GetMapping("404")
  public String notFound() {
    return "sys/exception/404";
  }

  @ApiOperation(value = "请求500页面", notes = "请求500页面")
  @GetMapping("500")
  public String serverError() {
    return "sys/exception/500";
  }
}

然后所需要的 exception.css

.error .clip .shadow {
  height: 180px;
}

.error .clip:nth-of-type(2) .shadow {
  width: 130px;
}

.error .clip:nth-of-type(1) .shadow, .error .clip:nth-of-type(3) .shadow {
  width: 250px;
}

.error .digit {
  width: 150px;
  height: 150px;
  line-height: 150px;
  font-size: 120px;
  font-weight: bold;
}

.error h2 {
  font-size: 32px;
}

.error .msg {
  top: -190px;
  left: 30%;
  width: 80px;
  height: 80px;
  line-height: 80px;
  font-size: 32px;
}

.error span.triangle {
  top: 70%;
  right: 0%;
  border-left: 20px solid #535353;
  border-top: 15px solid transparent;
  border-bottom: 15px solid transparent;
}

.error .container-error-404 {
  top: 50%;
  margin-top: 250px;
  position: relative;
  height: 250px;
  padding-top: 40px;
}

.error .container-error-404 .clip {
  display: inline-block;
  transform: skew(-45deg);
}

.error .clip .shadow {
  overflow: hidden;
}

.error .clip:nth-of-type(2) .shadow {
  overflow: hidden;
  position: relative;
  box-shadow: inset 20px 0px 20px -15px rgba(150, 150, 150, 0.8), 20px 0px 20px -15px rgba(150, 150, 150, 0.8);
}

.error .clip:nth-of-type(3) .shadow:after, .error .clip:nth-of-type(1) .shadow:after {
  content: "";
  position: absolute;
  right: -8px;
  bottom: 0px;
  z-index: 9999;
  height: 100%;
  width: 10px;
  background: linear-gradient(90deg, transparent, rgba(173, 173, 173, 0.8), transparent);
  border-radius: 50%;
}

.error .clip:nth-of-type(3) .shadow:after {
  left: -8px;
}

.error .digit {
  position: relative;
  top: 8%;
  color: white;
  background: #1E9FFF;
  border-radius: 50%;
  display: inline-block;
  transform: skew(45deg);
}

.error .clip:nth-of-type(2) .digit {
  left: -10%;
}

.error .clip:nth-of-type(1) .digit {
  right: -20%;
}

.error .clip:nth-of-type(3) .digit {
  left: -20%;
}

.error h2 {
  font-size: 24px;
  color: #A2A2A2;
  font-weight: bold;
  padding-bottom: 20px;
}

.error .tohome {
  font-size: 16px;
  color: #07B3F9;
}

.error .msg {
  position: relative;
  z-index: 9999;
  display: block;
  background: #535353;
  color: #A2A2A2;
  border-radius: 50%;
  font-style: italic;
}

.error .triangle {
  position: absolute;
  z-index: 999;
  transform: rotate(45deg);
  content: "";
  width: 0;
  height: 0;
}

@media (max-width: 767px) {
  .error .clip .shadow {
    height: 100px;
  }

  .error .clip:nth-of-type(2) .shadow {
    width: 80px;
  }

  .error .clip:nth-of-type(1) .shadow, .error .clip:nth-of-type(3) .shadow {
    width: 100px;
  }

  .error .digit {
    width: 80px;
    height: 80px;
    line-height: 80px;
    font-size: 52px;
  }

  .error h2 {
    font-size: 18px;
  }

  .error .msg {
    top: -110px;
    left: 15%;
    width: 40px;
    height: 40px;
    line-height: 40px;
    font-size: 18px;
  }

  .error span.triangle {
    top: 70%;
    right: -3%;
    border-left: 10px solid #535353;
    border-top: 8px solid transparent;
    border-bottom: 8px solid transparent;
  }

  .error .container-error-404 {
    height: 150px;
  }
}

所需要的 exception.js

.error .clip .shadow {
  height: 180px;
}

.error .clip:nth-of-type(2) .shadow {
  width: 130px;
}

.error .clip:nth-of-type(1) .shadow, .error .clip:nth-of-type(3) .shadow {
  width: 250px;
}

.error .digit {
  width: 150px;
  height: 150px;
  line-height: 150px;
  font-size: 120px;
  font-weight: bold;
}

.error h2 {
  font-size: 32px;
}

.error .msg {
  top: -190px;
  left: 30%;
  width: 80px;
  height: 80px;
  line-height: 80px;
  font-size: 32px;
}

.error span.triangle {
  top: 70%;
  right: 0%;
  border-left: 20px solid #535353;
  border-top: 15px solid transparent;
  border-bottom: 15px solid transparent;
}

.error .container-error-404 {
  top: 50%;
  margin-top: 250px;
  position: relative;
  height: 250px;
  padding-top: 40px;
}

.error .container-error-404 .clip {
  display: inline-block;
  transform: skew(-45deg);
}

.error .clip .shadow {
  overflow: hidden;
}

.error .clip:nth-of-type(2) .shadow {
  overflow: hidden;
  position: relative;
  box-shadow: inset 20px 0px 20px -15px rgba(150, 150, 150, 0.8), 20px 0px 20px -15px rgba(150, 150, 150, 0.8);
}

.error .clip:nth-of-type(3) .shadow:after, .error .clip:nth-of-type(1) .shadow:after {
  content: "";
  position: absolute;
  right: -8px;
  bottom: 0px;
  z-index: 9999;
  height: 100%;
  width: 10px;
  background: linear-gradient(90deg, transparent, rgba(173, 173, 173, 0.8), transparent);
  border-radius: 50%;
}

.error .clip:nth-of-type(3) .shadow:after {
  left: -8px;
}

.error .digit {
  position: relative;
  top: 8%;
  color: white;
  background: #1E9FFF;
  border-radius: 50%;
  display: inline-block;
  transform: skew(45deg);
}

.error .clip:nth-of-type(2) .digit {
  left: -10%;
}

.error .clip:nth-of-type(1) .digit {
  right: -20%;
}

.error .clip:nth-of-type(3) .digit {
  left: -20%;
}

.error h2 {
  font-size: 24px;
  color: #A2A2A2;
  font-weight: bold;
  padding-bottom: 20px;
}

.error .tohome {
  font-size: 16px;
  color: #07B3F9;
}

.error .msg {
  position: relative;
  z-index: 9999;
  display: block;
  background: #535353;
  color: #A2A2A2;
  border-radius: 50%;
  font-style: italic;
}

.error .triangle {
  position: absolute;
  z-index: 999;
  transform: rotate(45deg);
  content: "";
  width: 0;
  height: 0;
}

@media (max-width: 767px) {
  .error .clip .shadow {
    height: 100px;
  }

  .error .clip:nth-of-type(2) .shadow {
    width: 80px;
  }

  .error .clip:nth-of-type(1) .shadow, .error .clip:nth-of-type(3) .shadow {
    width: 100px;
  }

  .error .digit {
    width: 80px;
    height: 80px;
    line-height: 80px;
    font-size: 52px;
  }

  .error h2 {
    font-size: 18px;
  }

  .error .msg {
    top: -110px;
    left: 15%;
    width: 40px;
    height: 40px;
    line-height: 40px;
    font-size: 18px;
  }

  .error span.triangle {
    top: 70%;
    right: -3%;
    border-left: 10px solid #535353;
    border-top: 8px solid transparent;
    border-bottom: 8px solid transparent;
  }

  .error .container-error-404 {
    height: 150px;
  }
}

三、测试

项目启动后,我们访问一个并不存在的 API


那,通过访问一个项目中并不存在的 API,得到 404 页面,页面可以提示一些友好的文字,从而安抚用户紧张的心理,其实也是一个不错的选择吧

到此这篇关于SpringBoot中定制异常页面的实现方法的文章就介绍到这了,更多相关SpringBoot 定制异常页面内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Sa-Token中的SaSession对象使用学习示例详解

    Sa-Token中的SaSession对象使用学习示例详解

    这篇文章主要为大家介绍了Sa-Token中的SaSession对象使用学习示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • Java多线程Callable和Future接口区别

    Java多线程Callable和Future接口区别

    这篇文章主要介绍了Java多线程Callable和Future接口区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • SpringCache之 @CachePut的使用

    SpringCache之 @CachePut的使用

    这篇文章主要介绍了SpringCache之 @CachePut的使用,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • SpringBoot集成JWT令牌详细说明

    SpringBoot集成JWT令牌详细说明

    这篇文章主要介绍了SpringBoot集成JWT令牌详细说明,JWT方式校验方式更加简单便捷化,无需通过redis缓存,而是直接根据token取出保存的用户信息,以及对token可用性校验,单点登录,验证token更为简单,需要的朋友可以参考下
    2023-10-10
  • redis客户端Jedis使用小结

    redis客户端Jedis使用小结

    Jedis是Redis的一款Java语言的开源客户端连接工具,本文主要介绍了redis客户端Jedis使用,具有一定的参考价值,感兴趣的可以了解一下
    2023-11-11
  • Java 之类型转换与多态详情

    Java 之类型转换与多态详情

    Java使用类创造新的类型(type),并使用继承来便利我们创建类。再深一层讲类型,并是多态(polymorphism)的概念。本文将给大家介绍Java 的类型转换与多态,需要的小伙伴可以参考下面文章的具体内容
    2021-09-09
  • 浅谈spring aop的五种通知类型

    浅谈spring aop的五种通知类型

    这篇文章主要介绍了浅谈spring aop的五种通知类型,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12
  • Spring内置定时任务调度@Scheduled使用详解

    Spring内置定时任务调度@Scheduled使用详解

    这篇文章主要介绍了Spring内置定时任务调度@Scheduled使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-12-12
  • SpringBoot加载不出来application.yml文件的解决方法

    SpringBoot加载不出来application.yml文件的解决方法

    这篇文章主要介绍了SpringBoot加载不出来application.yml文件的解决方法,文中通过示例代码讲解的非常详细,对大家的学习或者工作有一定的帮助,需要的朋友跟着小编来一起来学习吧
    2023-12-12
  • 跨域解决方案Jsonp原理解析

    跨域解决方案Jsonp原理解析

    这篇文章主要介绍了跨域解决方案Jsonp原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02

最新评论