编辑
2024-06-06
后端
00
请注意,本文编写于 247 天前,最后修改于 247 天前,其中某些信息可能已经过时。

一切的起源来自与我使用 knife4j 时,一直被它这里默认有个 basic-error-controller 所困扰,一开始我不以为然,而后来我使用 openapi 自动生成前端接口时,因为文档中这个 basic-error-controller 导致代码看起来很奇怪。所以我经过一番搜索,找到了合适的解决方案

因为 knife4j 无法指定扫描的 controller 目录,以至于我一直无法处理掉这个 controller。 经过搜索发现,它是来自于 springboot 包下的一个 controller

罪魁祸首就是他们

spring boot 默认错误处理是这样的

  1. 浏览器,默认返回一个错误页面

  2. 如果是通过接口请求,它是这样的

它的原理大概是这样的

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 重写 errorHtmlerror 方法修改返回的数据或者页面

又由于继承的 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>

错误页面像这样

如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:peepdd864

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!