经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring » 查看文章
SpringBoot多种自定义错误页面方式小结
来源:jb51  时间:2021/11/29 12:51:55  对本文有异议

在项目中为了友好化,对于错误页面,我们常常会使用自定义的页面。SSM框架组合时代,我们通常通过拦截或者在web.xml中设置对于错误码的错误页面,然而到了SpringBoot,web.xml消失了,SpringBootServletInitializer初始化servlet代替了web.xml。难道要再把web.xml加回去?这样虽然可以做到,但并不合理。

下面提供了多种在SpringBoot中实现自定义错误页面的方法。

以前web.xml方式

先来看下在web.xml中配置错误页面的方式:

  1. <error-page>
  2. <error-code>404</error-code>
  3. <location>/error/404.jsp</location>
  4. </error-page>

SpringBoot中实现方式

在SpringBoot后,可以通过如下几种方式实现自定义错误页面。

1.实现EmbeddedServletContainerCustomizer的bean

适合内嵌服务器,先在controller中定义我们的错误页面Mapping,通过在配置类中实现EmbeddedServletContainerCustomizer的bean,加入对应状态码的错误页面。注意这种方式在打成war后,供外部tomcat使用时,将会失效。

定义错误页面:

  1. @RequestMapping(value = "/error/[code]")
  2. public String error(@PathVariable int code, Model model) {
  3. String pager = "/content/error-pager";
  4. switch (code) {
  5. case 404:
  6. model.addAttribute("code", 404);
  7. pager = "/content/error-pager";
  8. break;
  9. case 500:
  10. model.addAttribute("code", 500);
  11. pager = "/content/error-pager";
  12. break;
  13. }
  14. return pager;
  15. }

在配置类中加入EmbeddedServletContainerCustomizer:

  1. /**
  2. * 配置默认错误页面(仅用于内嵌tomcat启动时)
  3. * 使用这种方式,在打包为war后不起作用
  4. *
  5. * @return
  6. */
  7. @Bean
  8. public EmbeddedServletContainerCustomizer containerCustomizer() {
  9. return container -> {
  10. ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/error/404");
  11. ErrorPage error500Page = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500");
  12. container.addErrorPages(error404Page, error500Page);
  13. };

2.通过拦截器方式

适合内嵌Tomcat或者war方式。

  1. /**
  2. * @author hgs
  3. * @version ErrorPageInterceptor.java, v 0.1 2018/03/04 20:52 hgs Exp $
  4. * <p>
  5. * 错误页面拦截器
  6. * 替代EmbeddedServletContainerCustomizer在war中不起作用的方法
  7. */
  8. @Component
  9. public class ErrorPageInterceptor extends HandlerInterceptorAdapter {
  10. private List<Integer> errorCodeList = Arrays.asList(404, 403, 500, 501);
  11. @Override
  12. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws
  13. Exception {
  14. if (errorCodeList.contains(response.getStatus())) {
  15. response.sendRedirect("/error/" + response.getStatus());
  16. return false;
  17. }
  18. return super.preHandle(request, response, handler);
  19. }
  20. }

在配置类中添加拦截

  1. @Configuration
  2. public class WebMvcConfig extends WebMvcConfigurerAdapter {
  3. @Override
  4. public void addInterceptors(InterceptorRegistry registry) {
  5. registry.addInterceptor(errorPageInterceptor);//.addPathPatterns("/action/**", "/mine/**");默认所有
  6. super.addInterceptors(registry);
  7. }
  8. }

3.自定义静态error页面方法

在resource/templates下添加error.html页面,springBoot会自动找到该页面作为错误页面,适合内嵌Tomcat或者war方式。

SpringBoot错误视图提供了以下错误属性:

  • timestamp:错误发生时间;
  • status:HTTP状态吗;
  • error:错误原因;
  • exception:异常的类名;
  • message:异常消息(如果这个错误是由异常引起的);
  • errors:BindingResult异常里的各种错误(如果这个错误是由异常引起的);
  • trace:异常跟踪信息(如果这个错误是由异常引起的);
  • path:错误发生时请求的URL路径。

SpringBoot使用的前端框架模板不同,页面的名称也有所不同:

  • 实现Spring的View接口的Bean,其ID需要设置为error(由Spring的BeanNameViewResolver所解析);
  • 如果配置了Thymeleaf,则需命名为error.html的Thymeleaf模板;
  • 如果配置了FreeMarker,则需命名为error.ftl的FreeMarker模板;
  • 如果配置了Velocity,则需命名为error.vm的Velocity模板;
  • 如果是用JSP视图,则需命名为error.jsp的JSP模板。

Thymeleaf实例:

  1. <!DOCTYPE html>
  2. <html lang="en" xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4. <title th:text="${title}"></title>
  5. </head>
  6. <body class="layout">
  7. <div class="wrap">
  8. <!-- S top -->
  9. <div th:include="/header/module-header::module-header"></div>
  10. <!-- S 内容 -->
  11. <div class="panel-l container clearfix">
  12. <div class="error">
  13. <p class="title"><span class="code" th:text="${status}"></span>非常抱歉,没有找到您要查看的页面</p>
  14. <a href="/" rel="external nofollow" class="btn-back common-button">返回首页
  15. <img class="logo-back" src="/img/back.png">
  16. </a>
  17. <div class="common-hint-word">
  18. <div th:text="${#dates.format(timestamp,'yyyy-MM-dd HH:mm:ss')}"></div>
  19. <div th:text="${messages}"></div>
  20. <div th:text="${error}"></div>
  21. </div>
  22. </div>
  23. </div>
  24. </div>
  25. </div>
  26. </body>
  27. </html>

对于外部Tomcat第三中方案是比较推荐的一种实现方式,但不够灵活,我们不好定义自己的属性,如果想对其做相应修改,可以参见源码BasicErrorController,通过继承AbstractErrorController,并重写errorHtml方法,达到自己想要的效果。在内嵌Tomcat时,第一种推荐使用,更具灵活性。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持w3xue。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号