第一种方法:
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>