在Java里如何实现简易邮件通知系统_Java网络项目实践说明

用 JavaMail API 发送纯文本邮件最简路径是引入 jakarta.mail 依赖,配置 Session 时必须用 Authenticator 匿名子类传账号密码(即使无需认证),正确选择端口(587 for STARTTLS/465 for SSL)并避免 TLS 参数互斥,Gmail 等需启用两步验证并使用应用专用密码。

用 JavaMail API 发送纯文本邮件最简路径

Java 自带的 javax.mail(现为 jakarta.mail)是实现邮件通知最轻量、无需第三方服务依赖的选择。前提是你的环境能直连 SMTP 服务器(比如公司内网邮箱或已配置好 Relay 的邮件网关)。

关键不是“能不能发”

,而是“怎么绕过常见认证和 TLS 报错”。JDK 11+ 默认不带 javax.mail,必须显式引入依赖:

implementation 'com.sun.mail:jakarta.mail:2.0.1'

发送逻辑本身只需 10 行左右,但以下三点不处理,90% 的人卡在第一步:

  • Session 必须用 Authenticator 匿名子类传入账号密码(哪怕 SMTP 不需要认证,也得传个空实现,否则抛 AuthenticationFailedException
  • SMTP 端口不是固定 25:启用 STARTTLS 用 587,启用 SSL/TLS 用 465,两者不能混;mail.smtp.starttls.enablemail.smtp.ssl.enable 互斥,同时设 true 会静默失败
  • Gmail 或 Outlook 等公有邮箱必须开“应用专用密码”,且禁用“安全性较低的应用访问权限”——这个开关藏在 Google 账号设置里,不是邮箱设置

避免 javax.mail.AuthenticationFailedException 的真实原因

这个异常名字极具误导性:它不一定代表密码错了。更常见的触发条件是 SMTP 服务器拒绝了连接协商阶段的任意一环。

排查顺序应为:

  • 先 telnet 测试端口通不通:telnet smtp.gmail.com 587(Linux/macOS)或用 PowerShell Test-NetConnection smtp.gmail.com -Port 587
  • 确认 mail.smtp.auth 设为 true —— 即使服务器不要求认证,很多 SMTP 实现(如 Postfix)也强制要求客户端声明“我支持 auth”
  • 检查 mail.smtp.host 值是否含多余空格或 http:// 前缀(常见手误写成 http://smtp.gmail.com
  • 若用 Gmail,确保账号已开启两步验证,并生成了应用专用密码(不是你登录 Google 的密码)

Spring Boot 项目中注入 MailSender 的最小配置

如果你用 Spring Boot,别自己 new Session,直接配 JavaMailSender Bean。但注意:Spring Boot 2.6+ 默认不再自动装配 JavaMailSender,必须加 starter:

implementation 'org.springframework.boot:spring-boot-starter-mail'

application.yml 中只写必要项,其余交给 Spring 自动推导:

spring:
  mail:
    host: smtp.gmail.com
    port: 587
    username: your.email@gmail.com
    password: xxxxxxxxxxyyyyyyyyy  # 应用专用密码
    properties:
      mail:
        smtp:
          auth: true
          starttls:
            enable: true

使用时直接 @Autowired 注入 JavaMailSender,调用 send() 即可。注意:Spring 的 SimpleMailMessage 只支持纯文本,附件或 HTML 需用 MimeMessage + MimeMessageHelper

生产环境必须绕开的三个坑

本地能发 ≠ 上线能发。实际部署时,以下问题高频出现且日志极少提示:

  • 云服务器(如阿里云、腾讯云)默认封禁 25/465/587 出方向端口,需工单申请解封,或改用云厂商提供的邮件推送服务(如阿里云 DirectMail)
  • Docker 容器内 DNS 解析失败导致 UnknownHostException:在 docker run--dns 8.8.8.8,或在 Spring Boot 配置中把 host 换成 IP(如 142.250.191.109 代替 smtp.gmail.com
  • 频繁发送触发 SMTP 限流:Gmail 免费账号每 24 小时最多 500 封,超限后后续请求直接被静默丢弃(无异常),需加队列 + 重试 + 限速(如用 RateLimiter

真正的难点不在代码,而在让邮件从你的 JVM 进程真正抵达收件箱——中间隔着网络策略、DNS、反垃圾规则、收件方过滤器,每层都可能无声吞掉你的 MimeMessage