一、定制错误页面

  1、有模板引擎的情况下;error/状态码; 【将错误页面命名为 错误状态码.html 放在模板引擎文件夹里面的 error文件夹下】,发生此状态码的错误就会来到 对应的页面;

 

springboot打包无法打出依赖包 springboot打包错误_error


 我们可以使用4xx和5xx作为错误页面的文件名来匹配这种类型的所有错误,精确优先(优先寻找精确的状态 码.html);

  页面能获取的信息;

        timestamp:时间戳

       status:状态码

       error:错误提示

       exception:异常对象

       message:异常消息

       errors:JSR303数据校验的错误都在这里

 2、没有模板引擎(模板引擎找不到这个错误页面),静态资源文件夹下找;

springboot打包无法打出依赖包 springboot打包错误_错误定制_02

所以把error页面放到static文件夹下也ok,但是无法使用模板引擎解析数据
3、以上都没有错误页面,就是默认来到SpringBoot默认的错误提示页面;

二、定制错误的json数据

1、自定义异常处理&返回定制json数据

@RequestMapping("/hi")
    @ResponseBody
    public String hi(@RequestParam("user") String user)
    {
       if (user.equals("aaa")){
           throw new UserNotExistException();
         }
        return  "hello";
    }
public class UserNotExistException extends RuntimeException{
    public UserNotExistException() {
        super("用户不存在");
    }
}

浏览器访问:http://localhost:8081/crud/hi?user=111  (正常)

springboot打包无法打出依赖包 springboot打包错误_错误定制_03

浏览器访问:http://localhost:8081/crud/hi?user=aaa   

springboot打包无法打出依赖包 springboot打包错误_springboot打包无法打出依赖包_04

说明:页面中使用模板引擎解析数据

postman客户端访问:http://localhost:8081/crud/hi?user=aaa   

springboot打包无法打出依赖包 springboot打包错误_error_05

返回定制json数据

@ControllerAdvice
public class MyExceptionHandler {

    @ExceptionHandler(UserNotExistException.class)
    @ResponseBody
    public Map<String,Object> handlerException(Exception e){
        Map<String,Object> map = new HashMap<>();
        map.put("code","user not exit");
        map.put("message",e.getMessage());
        return map;
    }
}

浏览器访问:http://localhost:8081/crud/hi?user=aaa

springboot打包无法打出依赖包 springboot打包错误_springboot打包无法打出依赖包_06

postman客户端访问:http://localhost:8081/crud/hi?user=aaa

springboot打包无法打出依赖包 springboot打包错误_error_07

这种做法有一个缺点,就是浏览器和客户端返回的都是json数据,那么如何做到自适应呢?

方式一总结:实现了自定义错误页面和json数据,但是浏览器和客户端没有实现自适应

2、转发到/error进行自适应响应效果处理

@ControllerAdvice
public class MyExceptionHandler {
    @ExceptionHandler(UserNotExistException.class)
    public String handlerException(Exception e){
        Map<String,Object> map = new HashMap<>();
        map.put("code","user not exit");
        map.put("message",e.getMessage());
        //转发到/error进行自适应响应效果处理
        return "forward:/error";
    }

}

浏览器访问:http://localhost:8081/crud/hi?user=aaa

springboot打包无法打出依赖包 springboot打包错误_错误处理_08

postman客户端访问:http://localhost:8081/crud/hi?user=aaa

springboot打包无法打出依赖包 springboot打包错误_错误定制_09

但是这样做又成了默认了空白页面,而不是我们自定义的错误页面。注意到这里的错误状态码是200,而不是4XX,5XX

修改上述代码为:传入我们自己的错误状态码 4xx 5xx,否则就不会进入定制错误页面的解析流程 

@ExceptionHandler(UserNotExistException.class)
    public String handlerException(Exception e, HttpServletRequest request){
        Map<String,Object> map = new HashMap<>();
        request.setAttribute("javax.servlet.error.status_code",500);
        map.put("code","user not exit");
        map.put("message",e.getMessage());
        //转发到/error进行自适应响应效果处理
        return "forward:/error";
    }

浏览器访问:http://localhost:8081/crud/hi?user=aaa

springboot打包无法打出依赖包 springboot打包错误_error_10

postman客户端访问:http://localhost:8081/crud/hi?user=aaa

springboot打包无法打出依赖包 springboot打包错误_错误处理_11

这样做实现了自适应效果!!!!

方式二总结:实现了自定义错误页面,浏览器和额客户端实现了自适应,但是没有实现定制的json数据格式

3、将定制数据携带出去

出现错误以后,会来到/error请求,会被BasicErrorController处理,响应出去可以获取的数据是由 getErrorAttributes得到的(是AbstractErrorController(ErrorController)规定的方法);
  (1)完全来编写一个ErrorController的实现类【或者是编写AbstractErrorController的子类】,放在容器中;
 (2)页面上能用的数据,或者是json返回能用的数据都是通过errorAttributes.getErrorAttributes得到;
  容器中DefaultErrorAttributes.getErrorAttributes();默认进行数据处理的;
自定义ErrorAttributes
 

@Component
public class MyErrorAttributes extends DefaultErrorAttributes {

    @Override
    public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes, boolean includeStackTrace) {
        Map<String, Object> map = super.getErrorAttributes(requestAttributes, includeStackTrace);
        map.put("myerror","小新新自定义的错误呀");
        return map;
    }
}

浏览器访问:

springboot打包无法打出依赖包 springboot打包错误_错误处理_12

postman客户端访问:

springboot打包无法打出依赖包 springboot打包错误_错误处理_13

方式三总结:实现了自定义错误页面和定制的json数据格式,浏览器和额客户端实现了自适应

三、总结和代码整理

1、希望达到的效果:浏览器实现自定义页面相应,客户端相应自定义的json数据格式,浏览器和客户端自适应

(1)Controller

springboot打包无法打出依赖包 springboot打包错误_错误处理_14

(2)异常类 UserNotExistException

springboot打包无法打出依赖包 springboot打包错误_error_15

(3)异常处理器

springboot打包无法打出依赖包 springboot打包错误_springboot_16

这里需要写状态码!!!!

(4)定制错误属性

springboot打包无法打出依赖包 springboot打包错误_springboot打包无法打出依赖包_17

2、最终的效果:响应是自适应的,可以通过定制ErrorAttributes改变需要返回的内容,
浏览器访问:http://localhost:8081/crud/hi?user=aaa

springboot打包无法打出依赖包 springboot打包错误_springboot打包无法打出依赖包_18

postman客户端访问:http://localhost:8081/crud/hi?user=aaa

springboot打包无法打出依赖包 springboot打包错误_springboot_19

------------------------------------------------------------------------------------------------------------------------

补充说明:使用了springboot默认的错误处理机制,文件存放位置及格式如下:

springboot打包无法打出依赖包 springboot打包错误_error_20

EG:5XX.html

springboot打包无法打出依赖包 springboot打包错误_springboot_21