Java初学者项目实战:构建基本的电子邮件客户端

发布时间 - 2026-02-03 00:00:00    点击率:
Java初学者应使用jakarta.mail替代已废弃的javax.mail,因JDK 9+模块化移除了java.activation,旧版会抛NoClassDefFoundError;需显式引入jakarta.mail-api和com.sun.mail:jakarta.mail依赖,并正确配置TLS/SSL、应用专用密码及Authenticator。

Java初学者直接写完整邮件客户端容易卡在认证、SSL、协议细节上,不建议从零手撸 SMTP/IMAP 协议栈。用 javax.mail(现为 jakarta.

mail)是合理起点,但要注意 JDK 11+ 默认不包含它,且旧版 javax.mail:mail 已废弃。

为什么 javax.mail 会抛 NoClassDefFoundErrorClassNotFoundException

因为 JDK 9 开始模块化,java.activation 和邮件 API 全被移出默认 classpath;JDK 11 彻底删除 java.activation 模块。即使加了旧 jar,也会因缺少 javax.activation.DataSource 等类失败。

  • ✅ 正确做法:改用 jakarta.mail:jakarta.mail-api + com.sun.mail:jakarta.mail(推荐 2.0.1+)
  • ❌ 不要再用 javax.mail:mail:1.6.2 或更老版本
  • 若用 Maven,必须显式声明依赖,不能指望 JDK 自带

  jakarta.mail
  jakarta.mail-api
  2.1.3


  com.sun.mail
  jakarta.mail
  2.0.1

Session.getInstance(...)Session.getDefaultInstance(...) 的区别与风险

后者已被标记为 @Deprecated,且线程不安全:多个线程调用会共享同一 Session 实例,导致配置(如密码、host)被覆盖。前者才是标准用法,但需传入 Properties 和可选的 Authenticator

  • SMTP 发信必须设 mail.smtp.auth = "true",否则 Gmail/Outlook 等拒绝连接
  • 务必启用 TLS:mail.smtp.starttls.enable = "true"(Gmail 端口 587)或 SSL:mail.smtp.ssl.enable = "true"(端口 465)
  • 避免硬编码密码——用 Authenticator 子类延迟提供凭据,防止日志泄露
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.port", "587");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");

Session session = Session.getInstance(props, new Authenticator() {
  protected PasswordAuthentication getPasswordAuthentication() {
    return new PasswordAuthentication("user@gmail.com", "app-password-here");
  }
});

收邮件时 Store.connect(...)AuthenticationFailedException 的常见原因

Gmail/Outlook 等已停用“用户名+密码”直连,必须用应用专用密码(App Password)或 OAuth2。普通网页登录密码无效,且开启两步验证后才可生成应用密码。

  • Gmail:进入 Google 账户 → 安全 → 两步验证 → 应用专用密码(选“邮件”,生成 16 位密码)
  • Outlook:账户安全设置 → 高级安全选项 → 应用密码
  • IMAP 设置必须匹配:Gmail 是 imap.gmail.com:993mail.imaps.enable = "true",且用 Store.connect(host, user, password)
  • 别漏掉 folder.open(Folder.READ_ONLY),否则 getMessages() 返回空数组

初学者最容易忽略的权限与安全细节

本地测试时,IDE 运行的 Java 进程可能被系统防火墙拦截出站连接;企业网络常屏蔽 465/587/993 端口;而 Gmail 对异常登录行为(如新设备、非浏览器 UA)会静默拒收或进垃圾箱。

  • 发信后检查收件箱和垃圾邮件文件夹——Gmail 可能标记为“未加密发送”并降权
  • 收信前先 telnet 测试端口连通性:telnet smtp.gmail.com 587(需安装 telnet 客户端)
  • 不要在代码里写死邮箱密码,哪怕只是 demo;至少用 System.console().readPassword() 交互输入
  • 收到 javax.mail.AuthenticationFailedException: 535-5.7.8 Username and Password not accepted 时,90% 是密码错或未开应用专用密码

真正跑通收发,关键不在写多少行代码,而在确认每层协议(DNS 解析、TCP 连接、TLS 握手、SMTP/IMAP 认证)是否逐级通过。卡住时优先查网络和账号设置,而不是重写 Java 逻辑。


# word  # java  # go  # 编码  # 防火墙  # 浏览器  # app  # 端口  # ssl  # session  #   # ai  # outlook  # dns  # maven  # 子类 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 晋江文学城电脑版官网 晋江文学城网页版直接进入  Laravel如何使用API Resources格式化JSON响应_Laravel数据资源封装与格式化输出  简单实现jsp分页  Laravel如何升级到最新版本?(升级指南和步骤)  JavaScript如何实现类型判断_typeof和instanceof有什么区别  Win11怎么设置虚拟桌面 Win11新建多桌面切换操作【技巧】  Laravel如何监控和管理失败的队列任务_Laravel失败任务处理与监控  夸克浏览器网页跳转延迟怎么办 夸克浏览器跳转优化  Laravel中间件起什么作用_Laravel Middleware请求生命周期与自定义详解  如何在阿里云高效完成企业建站全流程?  如何获取免费开源的自助建站系统源码?  Bootstrap CSS布局之列表  详解一款开源免费的.NET文档操作组件DocX(.NET组件介绍之一)  Win11怎么恢复误删照片_Win11数据恢复工具使用【推荐】  网站制作怎么样才能赚钱,用自己的电脑做服务器架设网站有什么利弊,能赚钱吗?  电视网站制作tvbox接口,云海电视怎样自定义添加电视源?  如何用y主机助手快速搭建网站?  重庆市网站制作公司,重庆招聘网站哪个好?  WEB开发之注册页面验证码倒计时代码的实现  如何快速选择适合个人网站的云服务器配置?  Laravel如何创建和注册中间件_Laravel中间件编写与应用流程  百度输入法ai组件怎么删除 百度输入法ai组件移除工具  详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)  北京网站制作费用多少,建立一个公司网站的费用.有哪些部分,分别要多少钱?  打开php文件提示内存不足_怎么调整php内存限制【解决方案】  jimdo怎样用html5做选项卡_jimdo选项卡html5实现与切换效果【指南】  Laravel如何实现密码重置功能_Laravel密码找回与重置流程  html5的keygen标签为什么废弃_替代方案说明【解答】  如何快速搭建虚拟主机网站?新手必看指南  如何安全更换建站之星模板并保留数据?  Laravel如何与Vue.js集成_Laravel + Vue前后端分离项目搭建指南  佛山企业网站制作公司有哪些,沟通100网上服务官网?  Python文本处理实践_日志清洗解析【指导】  PHP 实现电台节目表的智能时间匹配与今日/明日轮播逻辑  ,南京靠谱的征婚网站?  Laravel如何处理CORS跨域请求?(配置示例)  深圳网站制作的公司有哪些,dido官方网站?  详解阿里云nginx服务器多站点的配置  HTML 中动态设置元素 name 属性的正确语法详解  阿里云网站搭建费用解析:服务器价格与建站成本优化指南  进行网站优化必须要坚持的四大原则  移动端手机网站制作软件,掌上时代,移动端网站的谷歌SEO该如何做?  如何在Windows 2008云服务器安全搭建网站?  网站制作企业,网站的banner和导航栏是指什么?  ChatGPT回答中断怎么办 引导AI继续输出完整内容的方法  如何用景安虚拟主机手机版绑定域名建站?  Android实现代码画虚线边框背景效果  如何使用 jQuery 正确渲染 Instagram 风格的标签列表  如何快速搭建高效简练网站?  Laravel Pest测试框架怎么用_从PHPUnit转向Pest的Laravel测试教程