本文目录导读:

在Java中实现异常通知(异常拦截)主要有以下几种常用方案,我为你整理了一个完整的案例参考:
Spring Boot全局异常拦截(最常用)
自定义异常类
// 自定义业务异常
public class BusinessException extends RuntimeException {
private Integer code;
private String message;
public BusinessException(Integer code, String message) {
super(message);
this.code = code;
this.message = message;
}
// getter/setter
}
全局异常处理器
@RestControllerAdvice
public class GlobalExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
// 处理自定义业务异常
@ExceptionHandler(BusinessException.class)
public Result handleBusinessException(BusinessException e) {
logger.warn("业务异常: {}", e.getMessage());
return Result.error(e.getCode(), e.getMessage());
}
// 处理参数校验异常
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result handleValidationException(MethodArgumentNotValidException e) {
String errorMsg = e.getBindingResult()
.getFieldErrors()
.stream()
.map(FieldError::getDefaultMessage)
.collect(Collectors.joining(","));
return Result.error(400, errorMsg);
}
// 处理所有未捕获异常
@ExceptionHandler(Exception.class)
public Result handleException(Exception e) {
logger.error("系统异常: ", e);
// 发送异常通知(邮件、短信等)
sendErrorNotification(e);
return Result.error(500, "服务器内部错误");
}
private void sendErrorNotification(Exception e) {
// 实现邮件/钉钉/企业微信通知逻辑
System.out.println("【异常通知】" + e.getMessage());
}
}
统一响应体
public class Result {
private Integer code;
private String message;
private Object data;
public static Result error(Integer code, String message) {
Result r = new Result();
r.code = code;
r.message = message;
return r;
}
// 其他getter/setter
}
使用AOP拦截异常
@Aspect
@Component
public class ExceptionAspect {
@Around("@annotation(ExceptionHandler)")
public Object handleException(ProceedingJoinPoint pjp) throws Throwable {
try {
return pjp.proceed();
} catch (BusinessException e) {
// 自定义业务异常处理
return Result.error(e.getCode(), e.getMessage());
} catch (Exception e) {
// 记录日志
log.error("方法: {} 异常: {}", pjp.getSignature(), e.getMessage());
// 发送通知
sendNotification(e);
return Result.error(500, "系统异常,请稍后重试");
}
}
}
// 自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExceptionHandler {
}
第三方通知集成示例
邮件通知
@Component
public class EmailNotifier {
@Autowired
private JavaMailSender mailSender;
@Value("${admin.email}")
private String adminEmail;
public void sendExceptionEmail(Exception e) {
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(adminEmail);
message.setSubject("【系统异常】" + e.getClass().getSimpleName());
message.setText("异常信息: " + e.getMessage() +
"\n堆栈信息: " + getStackTraceAsString(e));
mailSender.send(message);
}
private String getStackTraceAsString(Exception e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
return sw.toString();
}
}
钉钉机器人通知
@Component
public class DingTalkNotifier {
@Value("${dingtalk.webhook}")
private String webhookUrl;
public void sendDingTalkNotification(Exception e) {
String content = String.format(
"**系统异常通知**\n" +
"- 异常类型: %s\n" +
"- 异常信息: %s\n" +
"- 发生时间: %s\n" +
"- 堆栈: %s",
e.getClass().getSimpleName(),
e.getMessage(),
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")),
truncateStackTrace(e, 500)
);
RestTemplate restTemplate = new RestTemplate();
Map<String, Object> request = new HashMap<>();
request.put("msgtype", "markdown");
request.put("markdown", Map.of("title", "系统异常", "text", content));
restTemplate.postForEntity(webhookUrl, request, String.class);
}
}
使用Filter统一拦截
@Component
@WebFilter(urlPatterns = "/*")
public class ExceptionFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
try {
chain.doFilter(request, response);
} catch (Exception e) {
// 日志记录
log.error("Filter层异常: ", e);
// 发送通知
notificationService.sendException(e);
// 返回统一错误响应
HttpServletResponse resp = (HttpServletResponse) response;
resp.setContentType("application/json;charset=utf-8");
resp.getWriter().write(JSON.toJSONString(Result.error(500, "系统异常")));
}
}
}
配置优先级建议
# application.yml
exception:
notification:
enabled: true
types:
- email # 邮件通知
- dingtalk # 钉钉通知
# 忽略的异常类列表
ignore-exceptions:
- java.lang.IllegalArgumentException
- com.example.BusinessException
最佳实践建议
- 异常分类处理:区分业务异常和系统异常,不同处理方式
- 避免重复通知:相同异常短时间内只通知一次
- 异步通知:通知操作使用异步线程执行,不影响主业务
- 分级告警:按异常严重级别采用不同通知方式
- 通知去重:聚合相同异常,避免通知轰炸
这样实现的异常通知系统既能保证代码简洁,又能及时获取系统异常信息。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播