解决办法点这里
又是一个学SpringBoot的时候遇到的因为1和2版本差异造成的坑2333,看源码多多益善嘛
定制含有json格式内容的错误页面的时候,无法获取到异常类:
去查了下SpringBoot是如何默认配置错误处理的,首先还是ctrl+N跳到自动配置类:
应该是你没错了,点进去看看这货的源码,里面包含两个请求的mapping方法(一个处理浏览器请求返回html错误页面,一个处理客户端请求返回其他类型的错误信息,例如json):
@RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
@RequestMapping
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
查看任一方法体,不难注意到会调用getErrorAttributes方法将错误信息存到Map类型的model中:
Map<String, Object> model = Collections
.unmodifiableMap(getErrorAttributes(request, isIncludeStackTrace(request, MediaType.TEXT_HTML)));
于是再点进getErrorAttributes方法查看其源码:
protected Map<String, Object> getErrorAttributes(HttpServletRequest request, boolean includeStackTrace) {
WebRequest webRequest = new ServletWebRequest(request);
return this.errorAttributes.getErrorAttributes(webRequest, includeStackTrace);
}
被覆写了,再点返回的同名方法,跳到这个接口:
public interface ErrorAttributes {
然后ctrl+alt+B直接跳至实现类DefaultErrorAttributes,找到getErrorAttributes方法的实现:
public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
Map<String, Object> errorAttributes = new LinkedHashMap();
errorAttributes.put("timestamp", new Date());
this.addStatus(errorAttributes, webRequest);
this.addErrorDetails(errorAttributes, webRequest, includeStackTrace);
this.addPath(errorAttributes, webRequest);
return errorAttributes;
}
可以看到返回的数据包括时间戳、状态码、请求路径以及其它详细信息,所以接下来查看addErrorDetails方法的实现:
private void addErrorDetails(Map<String, Object> errorAttributes, WebRequest webRequest, boolean includeStackTrace) {
Throwable error = this.getError(webRequest);
if (error != null) {
while(true) {
if (!(error instanceof ServletException) || error.getCause() == null) {
if (this.includeException) {
errorAttributes.put("exception", error.getClass().getName());
}
this.addErrorMessage(errorAttributes, error);
if (includeStackTrace) {
this.addStackTrace(errorAttributes, error);
}
break;
}
error = error.getCause();
}
}
Object message = this.getAttribute(webRequest, "javax.servlet.error.message");
if ((!StringUtils.isEmpty(message) || errorAttributes.get("message") == null) && !(error instanceof BindingResult)) {
errorAttributes.put("message", StringUtils.isEmpty(message) ? "No message available" : message);
}
}
注意其中这个if:
if (this.includeException) {
errorAttributes.put("exception", error.getClass().getName());
}
拨云见日,答案很明显了,只有在includeException的值为true时,返回数据中才会加入异常类的类名。在实现类的开头也可以看到这个属性的相关配置,很容易得知其默认为false,需要将其置为true:
private final boolean includeException;
public DefaultErrorAttributes() { this(false); }
所以我们只需在配置文件里加上这一句:
server.error.include-exception=true
再看下错误页面: