第一种方法:
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;
}
}
运行:
所以无论是 客户端还是浏览器 都是以 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解析
}
}
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;
}
}
运行:
客户端:
如果网页的话你的定制一下 才能获取到: 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>