springboot错误页面显示

springboot默认的错误处理机制

默认效果

​ 1、直接返回错误信息,状态码等,404

在这里插入图片描述

​ 2、如果是其他客户端,默认响应一个json数据

定制错误响应页面

  • 如何定制错误页面(有模板的情况下)
    • 有模板的情况下;将错误页面命名为错误状态码.html,放在模板引擎文件夹里面的error文件夹下,发生此状态的错误,就会来到对应的页面。
    • 可以使用4xx、5xx作为错误页面的文件名来匹配这种类型的错误,优先匹配具体错误代码,如果没有,则使用代号页面

    在这里插入图片描述

    在这里插入图片描述

    • 页面中可以获取的信息:(defaultErrorAttributes.java)

      • timestamp:时间戳
      • status:状态码
      • error:错误提示
      • Exception:异常对象
      • message:异常消息
      • errors:jsr303数据校验的错误都在这里
    • 获取方式

      • 使用行内表达式

    在这里插入图片描述

  • 没有模板的情况下
    • 在static文件下下添加error文件下,具体错误页面命名和有模板时一样,但是没有模板的渲染
  • 以上都没有错误页面,则直接进入到bootstrap默认错误页面

自定义异常类并抛出异常

  • 先写一个异常类:
package springbootdemo.exception;

public class UserNotExistException extends RuntimeException{
    public UserNotExistException() {
        super("用户不存在");
    }
}
  • 在某个请求中抛出异常
package springbootdemo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import springbootdemo.exception.UserNotExistException;

@Controller
public class HelloController {
    @ResponseBody
    @GetMapping("/hello")
    public String hello(@RequestParam("user") String user){
        //在hello请求中获取user的值
        //当值等于admin的时候,抛出异常
        if ("admin".equals(user)) {
            throw new UserNotExistException();
        }
        return "hello,world";
    }
}
  • 定制html页面,显示异常信息
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h2>status:[[${status}]]</h2>
<h2>timestamp:[[${timestamp}]]</h2>
  <!--显示异常信息-->
<h2>message:[[${message}]]</h2>
  <!--显示异常对象-->
<h2>exception:[[${exception}]]</h2>
</body>
</html>

在这里插入图片描述

在这里插入图片描述

如何定制错误的json数据页面(其他客户端访问)

自定义异常&返回定制的json数据

没有自适应,无论在浏览器端还是其他移动端,都显示一样的数据

  • 创建一个异常处理类
package springbootdemo.controller;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import springbootdemo.exception.UserNotExistException;

import java.util.HashMap;
import java.util.Map;

@ControllerAdvice
public class MyExceptionHandler {
    @ResponseBody
    //出现异常时,springmvc将会把这个调用这个方法来处理异常
  	//注解表上要处理哪些异常
    @ExceptionHandler({UserNotExistException.class})
    public Map<String, Object> handlerException(Exception e){
        Map<String,Object> map = new HashMap<>();
      //定制返回信息,使用json格式
        map.put("code","user not exist");
        map.put("message",e.getMessage());
        return map;
        }
}

在这里插入图片描述

增加自适应

basicErrorController类可以处理/error请求,/error请求是自适应的

/error请求自适应:如果浏览器页面,则显示错误页面,如果是其他客户端,则显示json数据

  • 修改异常处理方法
@ExceptionHandler({UserNotExistException.class})
public String handlerException(Exception e){
    Map<String,Object> map = new HashMap<>();
    map.put("code","user not exist");
    map.put("message",e.getMessage());
    //转发到/error,让它来帮助进行自适应
    return "forward:/error";
}
  • 缺陷还是存在,出现错误之后又到了默认空白页面
    • 原因:错误视图没有解析到
    • 错误页面中错误状态码都为200,不是属于错误状态码
    • 解决方法:传入自己的错误状态码,不传递默认为200
//basicErrorController类中进行错误状态码的设置
HttpStatus status = this.getStatus(request);
if (status == HttpStatus.NO_CONTENT) {
    return new ResponseEntity(status);
} else {
    Map<String, Object> body = this.getErrorAttributes(request, this.getErrorAttributeOptions(request, MediaType.ALL));
    return new ResponseEntity(body, status);
}
@ExceptionHandler({UserNotExistException.class})
    public String handlerException(Exception e, HttpServletRequest request){
        Map<String,Object> map = new HashMap<>();
        //设置自己的错误状态码,默认为200,不会进入错误页面的解析流程,应该自己设置状态码
        /**
         * 在AbstractErrorController中使用如下方式设置错误状态码
         *Integer statusCode = (Integer)request.getAttribute("javax.servlet.error.status_code");
         */
        request.setAttribute("javax.servlet.error.status_code",500);
        map.put("code","user not exist");
        map.put("message",e.getMessage());
        //转发到/error,让它来帮助进行自适应
        return "forward:/error";
    }

在这里插入图片描述

  • 解决了自适应的问题,但是我们自己带入的错误数据没有显示(map.put("code","user not exist"); map.put("message",e.getMessage());
将定制的数据带出去

出现错误之后,会来到/error请求,会被basicErrorController类处理,响应出去可以获取的数据是由类中调用了abstractErrorController类(basicErrorController的父类,ErrorController的子类)中的getErrorAttributes()方法获取的。

basicErrorController(使用了@ConditionalOnMissingBean)在springboot中属于默认处理error请求的类,在没有自定义的情况下,默认使用

  • 解决方法

    • 完全编写一个ErrorController类(或者abstractErrorController),放在容器中

    • 页面上能用的数据,或者是json返回能用的数据都是通过errorAttributes(使用了@ConditionalOnMissingBean).getErrorAttributes得到的,

      在springboot中,就是使用defaultErrorAttributes.getErrorAttributes默认进行数据处理,所以,可以自定义一个MyErrorAttributes类

    /**
     * 在容器中添加自定义的errorattributes,来定制返回信息
     */
    @Component
    public class MyErrorAttributes  extends DefaultErrorAttributes {
        @Override
        public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) {
            Map<String, Object> map = super.getErrorAttributes(webRequest, options);
            //在这个map中添加自己的错误信息
            map.put("author","Zer0");
            return map;
        }
    }
    

    在这里插入图片描述

如何将异常处理器中的错误信息进行显示
  • 将异常处理器中的信息传递给自定义的errorattribute类中
@ExceptionHandler({UserNotExistException.class})
public String handlerException(Exception e, HttpServletRequest request){
    Map<String,Object> map = new HashMap<>();
    //设置自己的错误状态码,默认为200,不会进入错误页面的解析流程,应该自己设置状态码
    /**
     * 在AbstractErrorController中使用如下方式设置错误状态码
     *Integer statusCode = (Integer)request.getAttribute("javax.servlet.error.status_code");
     */
    request.setAttribute("javax.servlet.error.status_code",500);
    map.put("code","user not exist");
    map.put("message",e.getMessage());

    //将map放到request域中,通过setarttibutes方法进行设置
    request.setAttribute("ext",map);
    //转发到/error,让它来帮助进行自适应,同时将map带过去
    return "forward:/error";
}
  • 在MyErrorAttribute类中进行接收
public class MyErrorAttributes  extends DefaultErrorAttributes {
    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) {
        //这个map是页面和json获取的所有字段
        Map<String, Object> map = super.getErrorAttributes(webRequest, options);
        //在这个map中添加自己的错误信息
        map.put("author","Zer0");
        /**
         * 通过webRequest(封装之后的requestattribute)对象的getAttribute方法获取异常处理器中的信息
         * 两个参数:
         *  第一个是要获取的数据名
         *  第二个表上从哪里获取数据(session(1)、request(0))
         */
        Map<String,Object> ext = (Map<String, Object>) webRequest.getAttribute("ext", 0);
        //将信息合并
        map.put("ext",ext);
        return map;
    }

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值