24. SpringBoot 自定义异常信息

第一种方法:

1、自己写一个运行时异常

然后故意出现这个异常抛出异常【测试】

然后自定义一个异常解析器即可:

package com.bihu.component;

import com.bihu.Exception.UserNonExistentException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

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

@ControllerAdvice       //这个注解标志异常的
public class MyExceptionHandler{

    @ResponseBody
    @ExceptionHandler(UserNonExistentException.class)       //表示一旦抛出这个异常 此处理器就生效
    public Map<String,Object> exceptionHandling(Exception e) {
            Map<String,Object> result = new HashMap<>();
            result.put("message",e.getMessage());
            return  result;

    }

}
MyExceptionHandler

运行:

 

 

 所以无论是 客户端还是浏览器 都是以 JSON格式来返回错误信息,,,,,,这样的缺点就是自适应性不好。

 



 

第二种方法:【自适应性,浏览器解析网页;客户端解析为JSON】

在第一种的前提下,改变异常解析器

1.自定义自己的异常解析器:

package com.bihu.component;

import com.bihu.Exception.UserNonExistentException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@ControllerAdvice       //这个注解标志异常的
public class MyExceptionHandler{

    @ExceptionHandler(UserNonExistentException.class)       //表示一旦抛出这个异常 此处理器就生效
    public String exceptionHandling(Exception e, HttpServletRequest request) {
            //由于这里转发到error,所以这里的错误码永远是200成功 我们需要更改:
            request.setAttribute("javax.servlet.error.status_code",500);    //至于为啥 后面一起讲
            Map<String,Object> map = new HashMap<>();       //这里的参数是带不出去的 
            return "froward:/error";    //为了自适应性 转发到 /error页面 让SpringBoot解析
    }

}
异常解析器

运行发现 浏览器和客户端给出的都不一样了:

    

 

 

 

错误码是200我理解,为什么设置错误码是用request.setAttribute() ??? 查看源码得知 ,SpringBoot原始获取错误码是这样获取的:

 进入getStatus方法:

 

 

虽然方法是这样,但是我们想携带出去的数据是携带不出去的【自定义数据】,那么我们就得继续看源码:

可以清楚明白的看到是getErrorAttributes这个方法来获取数据内容的,跟进去看看:

 

 是getErrorAttributes ,这玩意其实就是 ErrorMvcAutoConfiguration 中的ConditionalOnMissingBean组件:

 

 

所以要在容器中加入组件ErrorAttributes,继承DefaultErrorAttributes类,然后重写getErrorAttributes,记得调用父类,详细这样写:

是容器中 不是组件哦,因为上面那个判断是判断是否存在那个容器是否生效默认。

 

异常解析器代码:

package com.bihu.component;

import com.bihu.Exception.UserNonExistentException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@ControllerAdvice       //这个注解标志异常的
public class MyExceptionHandler{

    @ExceptionHandler(UserNonExistentException.class)       //表示一旦抛出这个异常 此处理器就生效
    public String exceptionHandling(Exception e, HttpServletRequest request) {
            //由于这里转发到error,所以这里的错误码永远是200成功 我们需要更改:
            request.setAttribute("javax.servlet.error.status_code",500);    //至于为啥 后面一起讲
            Map<String,Object> map = new HashMap<>();
            map.put("info","抱歉,您的登录信息有误!");//装在自定义的错误信息
            request.setAttribute("ext",map);       //装在请求中 让异常解析器获取处理
            return "froward:/error";    //为了自适应性 转发到 /error页面 让SpringBoot解析
    }

}
异常解析器MyExceptionHandler
package com.bihu.component;

import org.springframework.boot.autoconfigure.web.DefaultErrorAttributes;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;

import java.util.Map;

@Component      //给容器中加组件
public class MyErrorAttributes extends DefaultErrorAttributes {
    @Override
    public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes, boolean includeStackTrace) {
        Map<String, Object> errorAttributes = super.getErrorAttributes(requestAttributes, includeStackTrace);
        Map<String,Object> ext = (Map<String,Object>)requestAttributes.getAttribute("ext", RequestAttributes.SCOPE_REQUEST);//这里获取request中我们呢自定义的信息
        errorAttributes.put("ext",ext);     //然后到外面去
        errorAttributes.put("company","BiHu");  //这还可以添加一些信息 一般添加公司标识

        return errorAttributes;
    }
}
MyErrorAttributes组件

运行:

客户端:

  

 

 

如果网页的话你的定制一下 才能获取到: 5xx.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

   <p>这个网页是模板功能情况下定义!注意!</p>
        <p>我自己自定义的信息:   [[${ext}]]</p>
        <p>时间:[[${timestamp}]]</p>
</body>
</html>

 

posted @ 2021-08-15 22:55  咸瑜  阅读(616)  评论(0编辑  收藏  举报