From 411565f8126b06255bd53e9de224087cf5669b52 Mon Sep 17 00:00:00 2001 From: zkh <1650697374@qq.com> Date: Sat, 14 Feb 2026 12:39:40 +0800 Subject: [PATCH] =?UTF-8?q?refactor(error):=20=E4=BC=98=E5=8C=96=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E9=94=99=E8=AF=AF=E6=8E=A7=E5=88=B6=E5=99=A8?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 SLF4J 日志记录功能 - 实现详细的错误信息提取和处理逻辑 - 增加对不同 HTTP 状态码的友好错误消息映射 - 添加错误日志记录,区分服务器错误和客户端错误 - 实现 getErrorPath 方法以符合 ErrorController 接口要求 - 添加详细的 JavaDoc 注释文档 --- .../web/controller/CustomErrorController.java | 79 ++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/zkh-web/src/main/java/vip/jcfd/web/controller/CustomErrorController.java b/zkh-web/src/main/java/vip/jcfd/web/controller/CustomErrorController.java index 6d7e7de..d57442a 100644 --- a/zkh-web/src/main/java/vip/jcfd/web/controller/CustomErrorController.java +++ b/zkh-web/src/main/java/vip/jcfd/web/controller/CustomErrorController.java @@ -2,6 +2,8 @@ package vip.jcfd.web.controller; import jakarta.servlet.RequestDispatcher; import jakarta.servlet.http.HttpServletRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.boot.web.servlet.error.ErrorController; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -9,15 +11,90 @@ import vip.jcfd.common.core.R; import java.util.Optional; +/** + * 自定义错误控制器 + * 重写 Spring MVC 默认的错误视图,返回 JSON 格式的错误响应 + */ @RestController public class CustomErrorController implements ErrorController { + private static final Logger log = LoggerFactory.getLogger(CustomErrorController.class); + + /** + * 处理错误请求 + * 根据 HTTP 状态码返回相应的错误信息 + */ @RequestMapping("/error") public R handleError(HttpServletRequest request) { + // 获取状态码 int status = Optional.ofNullable(request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE)) .map(Object::toString) .map(Integer::parseInt) .orElse(500); - return new R<>(status, "发生错误", false, null); + + // 获取请求 URI + String requestUri = Optional.ofNullable(request.getAttribute(RequestDispatcher.ERROR_REQUEST_URI)) + .map(Object::toString) + .orElse("unknown"); + + // 获取异常信息 + String exceptionMessage = Optional.ofNullable(request.getAttribute(RequestDispatcher.ERROR_MESSAGE)) + .map(Object::toString) + .orElse(null); + + // 获取异常类型 + String exceptionType = Optional.ofNullable(request.getAttribute(RequestDispatcher.ERROR_EXCEPTION_TYPE)) + .map(Object::toString) + .orElse(null); + + // 获取异常对象 + Throwable throwable = Optional.ofNullable(request.getAttribute(RequestDispatcher.ERROR_EXCEPTION)) + .filter(Throwable.class::isInstance) + .map(Throwable.class::cast) + .orElse(null); + + // 记录错误日志 + if (status >= 500) { + log.error("服务器错误 - 状态码: {}, 请求路径: {}, 异常类型: {}, 异常信息: {}", + status, requestUri, exceptionType, exceptionMessage, throwable); + } else if (status >= 400) { + log.warn("客户端错误 - 状态码: {}, 请求路径: {}, 异常信息: {}", + status, requestUri, exceptionMessage); + } + + // 根据状态码获取友好的错误消息 + String errorMessage = getErrorMessage(status, exceptionMessage); + + return new R<>(status, errorMessage, false, null); + } + + /** + * 根据状态码获取友好的错误消息 + */ + private String getErrorMessage(int status, String originalMessage) { + if (originalMessage != null && !originalMessage.isEmpty()) { + return originalMessage; + } + + return switch (status) { + case 400 -> "请求参数错误"; + case 401 -> "未授权,请先登录"; + case 403 -> "无权访问"; + case 404 -> "您访问的地址不存在"; + case 405 -> "请求方法不支持"; + case 500 -> "服务器内部错误"; + case 502 -> "网关错误"; + case 503 -> "服务暂时不可用"; + case 504 -> "网关超时"; + default -> "请求失败"; + }; + } + + /** + * 返回错误路径 + * 实现 ErrorController 接口要求 + */ + public String getErrorPath() { + return "/error"; } }