一切的起源来自与我使用
knife4j
时,一直被它这里默认有个 basic-error-controller 所困扰,一开始我不以为然,而后来我使用 openapi 自动生成前端接口时,因为文档中这个 basic-error-controller 导致代码看起来很奇怪。所以我经过一番搜索,找到了合适的解决方案
因为 knife4j
无法指定扫描的 controller 目录,以至于我一直无法处理掉这个 controller。
经过搜索发现,它是来自于 springboot
包下的一个 controller
罪魁祸首就是他们
spring boot 默认错误处理是这样的
浏览器,默认返回一个错误页面
如果是通过接口请求,它是这样的
它的原理大概是这样的
java@Controller
@RequestMapping("${server.error.path:${error.path:/error}}")
public class BasicErrorController extends AbstractErrorController {
@RequestMapping(produces = "text/html")//产生html类型的数据;浏览器发送的请求来到这个方法处理
public ModelAndView errorHtml(HttpServletRequest request,
HttpServletResponse response) {
HttpStatus status = getStatus(request);
Map<String, Object> model = Collections.unmodifiableMap(getErrorAttributes(
request, isIncludeStackTrace(request, MediaType.TEXT_HTML)));
response.setStatus(status.value());
//去哪个页面作为错误页面;包含页面地址和页面内容
ModelAndView modelAndView = resolveErrorView(request, response, status, model);
return (modelAndView == null ? new ModelAndView("error", model) : modelAndView);
}
@RequestMapping
@ResponseBody //产生json数据,其他客户端来到这个方法处理;
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
Map<String, Object> body = getErrorAttributes(request,
isIncludeStackTrace(request, MediaType.ALL));
HttpStatus status = getStatus(request);
return new ResponseEntity<Map<String, Object>>(body, status);
}
我们可以通过继承 BasicErrorController
重写 errorHtml
和 error
方法修改返回的数据或者页面
又由于继承的 controller 写到了我们自己的包下,于是我们可以轻易控制在 knife4j
中的显示
例如像我这样,使用 thymeleaf
生成页面,让错误页面看起来也很不错
java/**
* 覆盖SpringBoot 默认错误处理器
*/
@Controller
@ApiIgnore
public class ErrorController extends BasicErrorController {
public ErrorController(ErrorAttributes errorAttributes,
ServerProperties serverProperties,
List<ErrorViewResolver> errorViewResolvers) {
super(errorAttributes, serverProperties.getError(), errorViewResolvers);
}
/**
* 返回的html/text页面
*
* @param request
* @param response
* @return
*/
@Override
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
HttpStatus status = getStatus(request);
// 获取 Spring Boot 默认提供的错误信息,然后添加一个自定义的错误信息
Map<String, Object> model = getErrorAttributes(request,
getErrorAttributeOptions(request, MediaType.TEXT_HTML));
return new ModelAndView("errorPage", model, status);
}
/**
* 返回的json数据
*
* @param request
* @return
*/
@Override
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
HttpStatus status = getStatus(request);
// 获取 Spring Boot 默认提供的错误信息,然后添加一个自定义的错误信息
Map<String, Object> body = getErrorAttributes(request,
getErrorAttributeOptions(request, MediaType.TEXT_HTML));
return new ResponseEntity<>(R.error(ErrorCode.SYSTEM_ERROR).toMap(), status);
}
}
在 templates/errorPage.html
中写入页面内容
html<!doctype html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>系统错误</title>
<style>
样式...
</style>
</head>
<body>
<div style="display: flex;flex-direction: column;justify-content: center;align-items: center;height: 100vh;">
<svg width="254" height="294">
可以放个图片
</svg>
<table>
还可以将错误信息用表格的形式列出
<tr>
<td>timestamp</td>
<td th:text="${timestamp}"></td>
</tr>
<tr>
<td>status</td>
<td th:text="${status}"></td>
</tr>
<tr>
<td>error</td>
<td th:text="${error}"></td>
</tr>
<tr>
<td>message</td>
<td th:text="${message}"></td>
</tr>
<tr>
<td>path</td>
<td th:text="${path}"></td>
</tr>
</table>
</div>
</body>
</html>
错误页面像这样
本文作者:peepdd864
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!