精弘网络 Java 后端微课 - EP3 异常捕获与日志记录

507 字
3 分钟
精弘网络 Java 后端微课 - EP3 异常捕获与日志记录

接口日志记录#

@Slf4j
@Component
public class AccessLogFilter implements Filter {
static {
AnsiOutput.setEnabled(AnsiOutput.Enabled.ALWAYS);
}
private static AnsiColor getStatusColor(int status) {
return switch (status / 100) {
case 2 -> AnsiColor.GREEN;
case 4 -> AnsiColor.YELLOW;
case 5 -> AnsiColor.RED;
default -> AnsiColor.DEFAULT;
};
}
private static AnsiColor getMethodColor(String method) {
return switch (method) {
case "GET" -> AnsiColor.BLUE;
case "POST" -> AnsiColor.CYAN;
case "PUT" -> AnsiColor.YELLOW;
case "DELETE" -> AnsiColor.RED;
default -> AnsiColor.MAGENTA;
};
}
private static String getRemoteAddr(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
return ip == null ? request.getRemoteAddr() : ip;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
if (!(request instanceof HttpServletRequest req) || !(response instanceof HttpServletResponse res)) {
chain.doFilter(request, response);
return;
}
Instant start = Instant.now();
chain.doFilter(request, response);
Instant end = Instant.now();
long durationMs = Duration.between(start, end).toMillis();
int status = res.getStatus();
String method = req.getMethod();
String uri = req.getRequestURI();
String query = req.getQueryString();
String ip = getRemoteAddr(req);
// 彩色状态码
String colorStatus = AnsiOutput.toString(
getStatusColor(status),
status,
AnsiColor.DEFAULT
);
// 彩色方法
String colorMethod = AnsiOutput.toString(
getMethodColor(method),
method,
AnsiColor.DEFAULT
);
log.info("{} | {}ms | {} {} | IP: {}",
colorStatus,
durationMs,
String.format("%-6s", colorMethod),
uri + (query != null ? "?" + query : ""),
ip
);
}
}

自定义错误类型与错误码聚合#

@Getter
public class ApiException extends RuntimeException {
private final Integer errorCode;
private final String errorMsg;
public ApiException(Integer errorCode, String errorMsg) {
super(errorMsg);
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
public ApiException(Integer errorCode, String errorMsg, Throwable cause) {
super(errorMsg, cause);
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
}
@Getter
public enum ExceptionEnum {
INVALID_PARAMETER(200000, "参数错误"),
RESOURCE_NOT_FOUND(200001, "资源不存在"),
WRONG_USERNAME_OR_PASSWORD(200002, "用户名或密码错误"),
PERMISSION_NOT_ALLOWED(200003, "权限不足"),
NOT_FOUND_ERROR(200404, HttpStatus.NOT_FOUND.getReasonPhrase()),
SERVER_ERROR(200500, "系统错误, 请稍后重试"),
;
private final Integer errorCode;
private final String errorMsg;
ExceptionEnum(Integer errorCode, String errorMsg) {
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
}

错误捕获#

@ControllerAdvice
@Order(1000)
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseBody
public AjaxResult<Object> handleGlobalException(Exception e) {
HandlerUtils.logException(e);
return AjaxResult.fail(ExceptionEnum.SERVER_ERROR);
}
}

常见参数校验异常:

  • MethodArgumentNotValidException 参数校验错误
  • JsonMappingException Json解析失败
  • HttpMessageNotReadableException Json格式错误
  • ServletRequestBindingException Query参数错误

常见 404 异常:

  • NoResourceFoundException 路径不存在
  • HttpRequestMethodNotSupportedException 请求方法不支持

课外拓展#

这边列出一些可以课外研究研究的方面,以便你对 Spring 框架有更深的理解。

注意:这些教程可能与最新的 Spring 版本有所出入,有疑问可以多上网上搜搜,或者问 Qwen、Deepseek 等大语言模型。

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

精弘网络 Java 后端微课 - EP3 异常捕获与日志记录
https://blog.sugarmgp.cn/posts/summer-lessons-ep3/
作者
SugarMGP
发布于
2025-08-13
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
SugarMGP
大二学生
站点统计
文章
15
分类
4
标签
29
总字数
11,620
运行时长
0
最后活动
0 天前

文章目录