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.)是合理起点,但要注意 JDK 11+ 默认不包含它,且旧版 
javax.mail:mail 已废弃。
为什么 javax.mail 会抛 NoClassDefFoundError 或 ClassNotFoundException
因为 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-api2.1.3 com.sun.mail jakarta.mail2.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:993,mail.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测试教程

