Springboot错误页面和错误信息定制操作

目录
  • 1、错误页面自定义
  • 2、错误数据
    • 2.1 默认错误数据
    • 2.2 自定义错误数据

SpringBoot2.1.4错误处理机制

前面一片已经介绍了springboot错误处理的机制,其实从整个分析过程中我们已经大概知道如何定制了。

1、错误页面自定义

springboot有个默认的错误页面,但是开发时错误页面肯定是自己定义的。那该如何定义?

在DefaultErrorViewResolver类中有下面几个方法,

private ModelAndView resolve(String viewName, Map<String, Object> model) {
	// 定义视图名,这里我们可以确定视图名:error/错误码,例如:error/404,
    String errorViewName = "error/" + viewName;
    // 这里结合上面的errorViewName,其实就是在template目录下的error目录进行查找
    // 我们默认情况下是没有error目录,这里的provide最终值为null,代码较多就不一一展示,有兴趣的可以跟下去
    TemplateAvailabilityProvider provider = this.templateAvailabilityProviders.getProvider(errorViewName, this.applicationContext);
    // 根据判定,这里会接着调用下面的resolveResource方法
    return provider != null ? new ModelAndView(errorViewName, model) : this.resolveResource(errorViewName, model);
}
private ModelAndView resolveResource(String viewName, Map<String, Object> model) {
	//  getStaticLocations()获取的是静态资源路径:"classpath:/META-INF/resources/", "classpath:/resources/","classpath:/static/", "classpath:/public/"
    String[] var3 = this.resourceProperties.getStaticLocations();
    int var4 = var3.length;
	// 遍历上面的4个静态资源路径
    for(int var5 = 0; var5 < var4; ++var5) {
        String location = var3[var5];
        try {
            Resource resource = this.applicationContext.getResource(location);
            // 创建resource对象,例如error/404.html
            resource = resource.createRelative(viewName + ".html");
            // 查找在对应静态资源目录下是否有上面的这个资源对象,有就创建视图对象
            if (resource.exists()) {
                return new ModelAndView(new DefaultErrorViewResolver.HtmlResourceView(resource), model);
            }
        } catch (Exception var8) {
            ;
        }
    }
	// 都没找到就返回null,默认情况下是不存在error目录的,所以这里最终返回null
    return null;
}

在解析错误视图界面时,会依次去这几个目录:template/classpath:/META-INF/resources/classpath:/resources/classpath:/static/classpath:/public/,在这些目录下的error目录里找文件名是错误状态码的页面文件(404、500…)。

所以我们可以在这些目录下创建error目录,在里面创建HTML页面,但是在template下面的页面才能被thymeleaf模板引擎识别。

现在再去访问不存在路径时效果如下,因为是404错误

但是,错误状态码是很多的,不可能将所有的页面全部写出来,在DefaultErrorViewResolver类中有下面一段静态代码:

static {
    Map<Series, String> views = new EnumMap(Series.class);
    views.put(Series.CLIENT_ERROR, "4xx");
    views.put(Series.SERVER_ERROR, "5xx");
    SERIES_VIEWS = Collections.unmodifiableMap(views);
}

向map中添加了两个数据"4xx"、“5xx”,这个表示4开头或者5开头的错误,并且看到下面的:

 public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
 		// 按状态码精确查找
        ModelAndView modelAndView = this.resolve(String.valueOf(status.value()), model);
        // 若精确查找未找到再来模糊查找
        // status.series()方法可以自己看一下,就是在获取错误码的首位
        if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) {
            modelAndView = this.resolve((String)SERIES_VIEWS.get(status.series()), model);
        }
        return modelAndView;
    }

上面注释写的很清楚了,springboot首先按错误精确查找,若为找到再以错误码首位模糊查找,所以我们也可以将错误页面文件定义成 4xx.html 或者 5xx.html。

2、错误数据

2.1 默认错误数据

页面搞定了,那默认的错误数据有哪些呢?响应浏览器或者移动端错误请求的两个方法中都同时用到了getErrorAttributes方法,这个方法就是用来获取错误数据的。

    public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
        HttpStatus status = this.getStatus(request);
        Map<String, Object> model = Collections.unmodifiableMap(this.getErrorAttributes(request, this.isIncludeStackTrace(request, MediaType.TEXT_HTML)));
        response.setStatus(status.value());
        ModelAndView modelAndView = this.resolveErrorView(request, response, status, model);
        return modelAndView != null ? modelAndView : new ModelAndView("error", model);
    }
    @RequestMapping
    public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
        Map<String, Object> body = this.getErrorAttributes(request, this.isIncludeStackTrace(request, MediaType.ALL));
        HttpStatus status = this.getStatus(request);
        return new ResponseEntity(body, status);
    }

这个方法是属于DefaultErrorAttributes类的,用来定义默认错误属性。

    public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
        Map<String, Object> errorAttributes = new LinkedHashMap();
        errorAttributes.put("timestamp", new Date());
        this.addStatus(errorAttributes, webRequest);
        this.addErrorDetails(errorAttributes, webRequest, includeStackTrace);
        this.addPath(errorAttributes, webRequest);
        return errorAttributes;
    }

从这个方法及其里面调用其他几个方法跟踪可以知道有如下错误属性:

  • timestamp:时间戳
  • status:错误码
  • error:错误名
  • exception:异常类型
  • message:异常信息
  • trace:错误栈
  • path:错误路径

2.2 自定义错误数据

下面模拟一个场景,发起一个请求,然后触发一个自定义异常,自己添加一些错误信息,在页面上显示出来。 exception:

public class MyException extends RuntimeException {

    public MyException() {
        super("发生异常了");
    }
}

Controller:

@ResponseBody
@RequestMapping("/hello")
public String hello(@RequestParam("username") String username){
	// 当username值为aaa是抛出异常
    if(username.equals("aaa")){
        throw new MyException();
    }
    return "hello";
}

为了处理异常还要定义个异常处理器,关键点1:注意设置状态码的注释

@ControllerAdvice
public class ExceptionController {
	  @ExceptionHandler(MyException.class)
	  public String f(HttpServletRequest request){
	      // 这里要更改状态码,前面访问路径是没有问题的,所以状态码为200
	      // 若想要进入springboot错误处理流程,必须重设状态码
	      // 并且其key值为:javax.servlet.error.status_code
	      request.setAttribute("javax.servlet.error.status_code",500);
	      // 这里可以添加信息到request中,到后面的取出添加到map中
	      request.setAttribute("data","我的错误消息");
	      // 转发到 /error请求,交给springboot处理
	      return "forward:/error";
	  }
}

关键点2,因为我们的错误信都是在DefaultErrorAttributes类中的getErrorAttributes方法中获取的,若只是到上面步骤为止,那么在移动端将无法获取到添加的data,所以为止同时使用浏览器和移动端,我们还必须创建一个类继承DefaultErrorAttributes类,重写getErrorAttributes方法,在这里才是真正的添加自定义的数据。

MyErrorAttribute

// 注意,给类必须添加到容器中,否则不生效
// 添加后将会覆盖原有的DefaultErrorAttributes,采用我们自己的MyErrorAtribute
@Component
public class MyErrorAtribute extends DefaultErrorAttributes {
    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
        // 获取包含错误信息的map
        Map<String, Object> map = super.getErrorAttributes(webRequest, includeStackTrace);
        // 添加自己的错误数据
        map.put("company","lr");
        //获取转发过来时添加的数据
        // 第二个参数表示在哪个域中获取,0:request,1:session
        String data = (String)webRequest.getAttribute("data", 0);
        map.put("data",data); // 添加到map
        return map;
    }
}

然后我们测试,浏览器端:

移动端:

这样,我们错误页面,错误消息自定义,浏览器和移动端适配都解决了。

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

(0)

相关推荐

  • Springboot实现自定义错误页面的方法(错误处理机制)

    一般我们在做项目的时候,错误机制是必备的常识,基本每个项目都会做错误处理,不可能项目一报错直接跳到原始报错页面,本篇博客主要针对springboot默认的处理机制,以及自定义错误页面处理进行讲解,需要的朋友们下面随着小编来一起学习学习吧! 默认效果示例 springboot他是有自己默认的处理机制的.在你刚创建一个springboot项目去访问一个没有的路径会发现他是会弹出来这样的信息. 而我们用postman直接接口访问,会发现他返回的不再是页面.默认响应一个json数据 这时候该有人在想,s

  • SpringBoot2.3定制错误页面的方法示例

    一. 问题背景 后台: SpringBoot 2.3.1(官方2.3版本修改了很多,抛弃了很多以前能用的方法) 前端: Layui(前端用哪个框架问题不大) 技术: SpringBoot+Thymeleaf+Layui 情况:我想将Layui提供好的错误页面作为SpringBoot默认的错误页面,而且Layui提供的错误页面位置并不是放在/静态资源文件夹/error,而是在如下: 二. SpringBoot的错误页面机制 错误页面机制的原理详情可以看Day41--错误处理原理&定制错误页面以及D

  • SpringBoot 利用thymeleaf自定义错误页面

    导入thymeleaf <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> 自定义异常类 建立监听异常类 MyException.class package com.example.demo.domain; public class My

  • springboot 自定义404、500错误提示页面的实现

    目录 springboot 默认的异常处理机制 使用模板引擎 使用示例 没有使用模板引擎 springboot 默认的异常处理机制 springboot 默认已经提供了一套处理异常的机制.一旦程序中出现了异常 springboot 会向 /error 的 url 发送请求.在 springboot 中提供了一个名为 BasicErrorController 的类来处理 /error 请求,然后跳转到默认显示异常的页面来展示异常信息 使用模板引擎 在使用 thymeleaf 等模板引擎时,spri

  • Springboot错误页面和错误信息定制操作

    目录 1.错误页面自定义 2.错误数据 2.1 默认错误数据 2.2 自定义错误数据 SpringBoot2.1.4错误处理机制 前面一片已经介绍了springboot错误处理的机制,其实从整个分析过程中我们已经大概知道如何定制了. 1.错误页面自定义 springboot有个默认的错误页面,但是开发时错误页面肯定是自己定义的.那该如何定义? 在DefaultErrorViewResolver类中有下面几个方法, private ModelAndView resolve(String viewN

  • ThinkPHP中自定义错误页面和提示页面实例

    本文实例讲述了ThinkPHP中自定义错误页面和提示页面的方法.分享给大家供大家参考.具体实现方法如下: 在ThinkPHP中有两个方法时提示错误页面 _404('错误信息','跳转的地址');halt('提示信息'); 这两个函数都可以自定义错误页面在配置文件中加 复制代码 代码如下: 'TMPL_EXCEPTION_FILE'=>'./Public/Tpl/error.html' 这样每次就会跳转到这个页面. 下面是我定制的错误页面 复制代码 代码如下: 在( 3 )秒后自动跳转,或直接点击

  • SpringBoot定制三种错误页面及错误数据方法示例

    目录 定制错误页面 自定义 error.html 自定义动态错误页面 自定义静态错误页面 定制错误数据 1. 自定义异常处理类 2. 自定义错误属性处理工具 我们知道 Spring Boot 已经提供了一套默认的异常处理机制,但是 Spring Boot 提供的默认异常处理机制却并不一定适合我们实际的业务场景,因此,我们通常会根据自身的需要对 Spring Boot 全局异常进行统一定制,例如定制错误页面,定制错误数据等. 定制错误页面 我们可以通过以下 3 种方式定制 Spring Boot

  • 定制404错误页面,并发信给管理员的程序

    如果您的用户找不到他要的页面,如何给他一个友好的答复,并且你也知道发生了这个错误呢,看看下面这段程序,是用来定制404错误页面和发通知给网管的好东西.---teaman翻译整理 <?php # 设置 $domain 为你的域名 (注意没有www) $domain = "oso.com.cn"; # 设置URL,注意没有后划线 / $docroot = "http://www.oso.com.cn"; # 设置错误信息的字体 $fontface = "

  • ASP.NET Core应用错误处理之ExceptionHandlerMiddleware中间件呈现“定制化错误页面”

    前言 DeveloperExceptionPageMiddleware中间件利用呈现出来的错误页面实现抛出异常和当前请求的详细信息以辅助开发人员更好地进行纠错诊断工作,而ExceptionHandlerMiddleware中间件则是面向最终用户的,我们可以利用它来显示一个友好的定制化的错误页面.按照惯例,我们还是先来看看ExceptionHandlerMiddleware的类型定义. public class ExceptionHandlerMiddleware { public Excepti

  • SpringBoot多种自定义错误页面方式小结

    目录 以前web.xml方式 SpringBoot中实现方式 1.实现EmbeddedServletContainerCustomizer的bean 2.通过拦截器方式 3.自定义静态error页面方法 在项目中为了友好化,对于错误页面,我们常常会使用自定义的页面.SSM框架组合时代,我们通常通过拦截或者在web.xml中设置对于错误码的错误页面,然而到了SpringBoot,web.xml消失了,SpringBootServletInitializer初始化servlet代替了web.xml.

  • Laravel5框架自定义错误页面配置操作示例

    本文实例讲述了Laravel5框架自定义错误页面配置操作.分享给大家供大家参考,具体如下: ♩ 背景 最近试着学习 laravel 5.5,使用 composer 下载新的框架源代码 composer create-project --prefer-dist laravel/laravel lar5Pro 5.5.* 发现在输入错误的链接时,会有如下的提示信息: 想到,一般成型的网站都会自定义404.501.503等页面,所以通过网上搜索方法,进行测试,可推荐如下的实现过程 - 框架: Lara

随机推荐