使用 @controlleradvice 配合 @exceptionhandler 可以全局捕获邮件发送异常。具体做法是定义一个处理类,在方法上指定要捕获的异常类型(如 mailsendexception),并在方法内返回统一的错误响应或记录日志。这样当任何地方抛出邮件发送失败时,spring boot 会自动拦截并执行该逻辑。

@ControllerAdvice 如何配置以捕获特定异常?
通过继承 ResponseEntityExceptionHandler 或直接标注 @RestControllerAdvice 来创建全局处理器。在处理方法中,使用 @ExceptionHandler({ MailSendException.class }) 注解声明只处理邮件相关的异常。这样可以将业务代码与异常处理逻辑解耦,确保邮件发送失败时不会导致整个应用崩溃,而是返回友好的提示。

import org.springframework.mail.MailSendException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.http.ResponseEntity;
import java.util.HashMap;
import java.util.Map;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MailSendException.class)
public ResponseEntity<Map<String, Object>> handleMailException(MailSendException ex) {
Map<String, Object> body = new HashMap<>();
body.put("error", "邮件发送失败");
body.put("message", ex.getMessage());
return ResponseEntity.status(500).body(body);
}
}
如何处理非邮件类的通用运行时异常?
除了邮件异常,通常还需要处理其他未预期的运行时异常。可以在同一个 @RestControllerAdvice 类中添加另一个方法,使用 @ExceptionHandler(RuntimeException.class) 来捕获所有运行时异常。这作为兜底策略,防止因未知错误导致系统无响应。该方法应返回通用的错误信息,避免暴露内部堆栈细节给前端。

import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.http.ResponseEntity;
import java.util.HashMap;
import java.util.Map;
// ... 上面的 GlobalExceptionHandler 类继续
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<Map<String, Object>> handleRuntimeException(RuntimeException ex) {
Map<String, Object> body = new HashMap<>();
body.put("error", "系统内部错误");
body.put("message", "请稍后重试");
// 实际生产中应记录日志: log.error("Runtime exception", ex);
return ResponseEntity.status(500).body(body);
}
邮件发送失败时,事务回滚机制是否生效?
如果邮件发送是在一个 @Transactional 方法中进行的,且邮件发送失败抛出了 MailSendException,默认情况下 Spring 的事务管理器会捕获该异常并触发事务回滚。这是因为 MailSendException 是 RuntimeException 的子类。这意味着如果邮件发送前保存了用户数据,邮件发送失败会导致用户数据也被回滚,从而保证数据一致性。


















