# mail-send-box **Repository Path**: personal_learn/mail-send-box ## Basic Information - **Project Name**: mail-send-box - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-01-04 - **Last Updated**: 2026-01-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 邮件发送客户端 一个功能完整的Java GUI邮件发送客户端,支持多变量配置和HTML格式正文。 **⚠️ 本项目仅供学习,违法后果自负。** ## 功能特性 - ✅ 图形化界面,支持SMTP(SSL/TLS) - ✅ 发件人显示名、主题与HTML正文变量化(`${变量名}`) - ✅ 变量配置区支持随机变量 - ✅ 收件人导入与并发批量发送 - ✅ SOCKS5 / HTTP 代理 - ✅ 发送日志与成功/失败统计 - ✅ URL配置区与“刷新域名”按钮 - ✅ 成功/失败日志文件实时写入(失败含原因) - ✅ 连接测试与状态提示 ## 功能总览表(含入口/行为/持久化/代码位置) | 模块 | 功能点 | UI/入口 | 行为细节 | 配置/文件输出 | 代码位置 | |---|---|---|---|---|---| | 启动与外观 | 启动主窗体 | main() | 设置系统 Look&Feel,启动 Swing UI | 无 | [MailClientGUI.java:L59-L73](src/main/java/com/mailclient/MailClientGUI.java#L59-L73) | | 启动与外观 | 顶部免责声明 | 初始化GUI | 顶部红字“免责声明…” | 无 | [MailClientGUI.java:L476-L491](src/main/java/com/mailclient/MailClientGUI.java#L476-L491) | | 启动与外观 | 生产/开发模式开关(实际锁死) | 顶部“模式”下拉框 | `ALLOW_DEV_SWITCH=false` 时无法切换到开发模式;`loadConfig` 也强制回生产 | config.properties 写 `mode=prod` | [MailClientGUI.java:L495-L507](src/main/java/com/mailclient/MailClientGUI.java#L495-L507)
[MailClientGUI.java:L2563-L2566](src/main/java/com/mailclient/MailClientGUI.java#L2563-L2566) | | 启动与外观 | 重置布局分隔条 | 顶部“重置布局” | 重置左右/中间-说明/说明-变量/内容-日志 4 个分割比例 | 分割比例会保存/加载 | [MailClientGUI.java:L509-L516](src/main/java/com/mailclient/MailClientGUI.java#L509-L516)
[MailClientGUI.java:L2219-L2226](src/main/java/com/mailclient/MailClientGUI.java#L2219-L2226)
[MailClientGUI.java:L2567-L2576](src/main/java/com/mailclient/MailClientGUI.java#L2567-L2576) | | 启动与外观 | 主题(明/暗) | 启动时/加载配置 | `applyTheme` 切换配色并重绘;theme 保存到配置 | config.properties: `theme=dark/light` | [MailClientGUI.java:L2120-L2143](src/main/java/com/mailclient/MailClientGUI.java#L2120-L2143)
[MailClientGUI.java:L2536-L2539](src/main/java/com/mailclient/MailClientGUI.java#L2536-L2539) | | 启动与外观 | 应用图标 | 启动时 `applyAppIcon` | 优先读用户目录 `icon.png`;否则读 resources/app-icon.png;再否则生成“M”图标并写入 icon.png 和 app-icon.png | `~/.mail_send_box/icon.png`;项目根 app-icon.png(运行时写) | [MailClientGUI.java:L563-L616](src/main/java/com/mailclient/MailClientGUI.java#L563-L616) | | 配置持久化 | 基础目录 | 启动/预览/日志 | 统一在用户目录 `~/.mail_send_box` 下读写 | 目录:`~/.mail_send_box` | [MailClientGUI.java:L138-L145](src/main/java/com/mailclient/MailClientGUI.java#L138-L145)
[MailClientGUI.java:L158-L163](src/main/java/com/mailclient/MailClientGUI.java#L158-L163) | | 配置持久化 | 保存配置 | “保存配置”按钮 | 保存配置 | config.properties / smtp.properties / proxy.properties / url.txt / recipients.txt | [MailClientGUI.java:L1092-L1100](src/main/java/com/mailclient/MailClientGUI.java#L1092-L1100)
[MailClientGUI.java:L2201-L2349](src/main/java/com/mailclient/MailClientGUI.java#L2201-L2349) | | 配置持久化 | 加载配置 | 启动时 `loadConfig` | 若存在独立 smtp.properties/proxy.properties 优先读;否则回退 config.properties;加载收件人时会过滤无效地址;加载后刷新收件人计数 | 同上 | [MailClientGUI.java:L2416-L2578](src/main/java/com/mailclient/MailClientGUI.java#L2416-L2578) | | SMTP(单项模板) | SMTP 主机/端口/用户/密码/SSL/TLS | 左侧“SMTP服务器配置”表单 | “测试连接”按钮用这里的配置发起连接测试;发送邮件实际用“多SMTP列表”,不是用表单单项 | smtp.properties 保存单项字段 | [MailClientGUI.java:L626-L741](src/main/java/com/mailclient/MailClientGUI.java#L626-L741)
[MailClientGUI.java:L1207-L1240](src/main/java/com/mailclient/MailClientGUI.java#L1207-L1240)
[MailClientGUI.java:L1338-L1341](src/main/java/com/mailclient/MailClientGUI.java#L1338-L1341) | | SMTP(多配置) | 多SMTP列表与策略 | 左侧“多SMTP配置与策略” | 支持添加/更新/删除/载入到表单/测试所选/重置计数;策略:随机/智能(基于成功率/延迟/失败率) | smtp.properties(含每项 daily.sent、指标) | [MailClientGUI.java:L742-L803](src/main/java/com/mailclient/MailClientGUI.java#L742-L803)
[MailClientGUI.java:L2838-L2965](src/main/java/com/mailclient/MailClientGUI.java#L2838-L2965)
[SmtpSelector.java:L6-L56](src/main/java/com/mailclient/SmtpSelector.java#L6-L56) | | SMTP(多配置) | SMTP 唯一性校验 | 添加/更新 SMTP | host+port+username 必须唯一(否则弹窗) | 无 | [MailClientGUI.java:L2926-L2937](src/main/java/com/mailclient/MailClientGUI.java#L2926-L2937)
[MailClientGUI.java:L2838-L2845](src/main/java/com/mailclient/MailClientGUI.java#L2838-L2845) | | SMTP(多配置) | SMTP 配置合法性过滤 | 发送前 | host/port/user/pass 必填且 port 全数字,否则该项被忽略,并在日志汇总“已忽略无效SMTP项” | 无 | [MailClientGUI.java:L451-L462](src/main/java/com/mailclient/MailClientGUI.java#L451-L462)
[MailClientGUI.java:L1395-L1411](src/main/java/com/mailclient/MailClientGUI.java#L1395-L1411) | | 配额与限流 | 按SMTP速率限制(封/秒 或 秒/封) | 发送时 | secondsPerEmail>0 时优先用“秒/封”;否则用“封/秒”;每个 SMTP 配置独立 RateLimiter;0 表示不限流 | 内存:rateLimiters;重置会清空 | [MailClientGUI.java:L357-L408](src/main/java/com/mailclient/MailClientGUI.java#L357-L408)
[MailClientGUI.java:L3195](src/main/java/com/mailclient/MailClientGUI.java#L3195) | | 配额与限流 | 按SMTP每日上限(封/日) | 发送时 | `tryReserveQuota` CAS 预占名额;失败则换 SMTP;发送失败会 `releaseQuota` 回滚;当天变更会清空计数 | smtp.properties 保存每项 daily.sent + daily.date | [MailClientGUI.java:L410-L470](src/main/java/com/mailclient/MailClientGUI.java#L410-L470)
[MailClientGUI.java:L2281-L2283](src/main/java/com/mailclient/MailClientGUI.java#L2281-L2283)
[MailClientGUI.java:L2476-L2494](src/main/java/com/mailclient/MailClientGUI.java#L2476-L2494) | | 代理(单项模板) | 代理开关/类型/主机/端口/账号密码 | 左侧“代理配置”表单 | 发送时若启用代理:优先从“多代理列表”选;否则回退表单;支持测试代理连通性(SOCKS 实测连到 SMTP;HTTP 只测连到代理端口) | proxy.properties 保存单项字段 | [MailClientGUI.java:L808-L879](src/main/java/com/mailclient/MailClientGUI.java#L808-L879)
[MailClientGUI.java:L2810-L2819](src/main/java/com/mailclient/MailClientGUI.java#L2810-L2819)
[MailClientGUI.java:L2583-L2649](src/main/java/com/mailclient/MailClientGUI.java#L2583-L2649) | | 代理(多配置) | 多代理列表与策略 | 左侧“多代理配置与策略” | 支持添加/更新/删除/载入到表单/测试所选;策略:随机/智能(同 SMTP 评分逻辑) | proxy.properties 保存多项 + 指标 | [MailClientGUI.java:L880-L933](src/main/java/com/mailclient/MailClientGUI.java#L880-L933)
[MailClientGUI.java:L2871-L2990](src/main/java/com/mailclient/MailClientGUI.java#L2871-L2990)
[ProxySelector.java:L6-L56](src/main/java/com/mailclient/ProxySelector.java#L6-L56) | | 代理(多配置) | 代理唯一性校验 | 添加代理 | 仅当 type=SOCKS5 时要求 host+port 唯一;HTTP 不做唯一性校验 | 无 | [MailClientGUI.java:L2871-L2880](src/main/java/com/mailclient/MailClientGUI.java#L2871-L2880)
[MailClientGUI.java:L3005-L3015](src/main/java/com/mailclient/MailClientGUI.java#L3005-L3015) | | 收件人 | 输入与发送参数 | 左侧“收件人模版”Tab | 支持多行、逗号、分号;并发线程数 1-50;起始位置可高亮定位;重置位置按钮设为 0 | 起始位置保存到 config.properties;收件人保存到 recipients.txt | [MailClientGUI.java:L934-L960](src/main/java/com/mailclient/MailClientGUI.java#L934-L960)
[MailClientGUI.java:L1693-L1705](src/main/java/com/mailclient/MailClientGUI.java#L1693-L1705) | | 收件人 | 导入收件人列表 | “导入收件人列表” | 支持 txt/csv;识别 `# send.offset=` 设置起始位置;按逗号/分号/空白拆分;去重保持顺序 | 导入只进文本框,不自动保存 | [MailClientGUI.java:L3328-L3365](src/main/java/com/mailclient/MailClientGUI.java#L3328-L3365)
[MailClientGUI.java:L3405-L3417](src/main/java/com/mailclient/MailClientGUI.java#L3405-L3417) | | 收件人 | 导出收件人列表 | “导出收件人列表” | 导出首行写 `# send.offset=`;忽略空行/注释;拆分并去重后逐行输出 | 导出为 txt 文件 | [MailClientGUI.java:L3367-L3399](src/main/java/com/mailclient/MailClientGUI.java#L3367-L3399) | | 收件人 | 过滤无效邮箱(读取/保存时) | loadConfig / saveConfig | 使用 `InternetAddress` 严格校验并去重;无效地址直接剔除;保存后会回写到 recipientsArea | recipients.txt 始终是“已过滤版本” | [MailClientGUI.java:L1153-L1171](src/main/java/com/mailclient/MailClientGUI.java#L1153-L1171)
[MailClientGUI.java:L2540-L2551](src/main/java/com/mailclient/MailClientGUI.java#L2540-L2551)
[MailClientGUI.java:L2339-L2347](src/main/java/com/mailclient/MailClientGUI.java#L2339-L2347) | | 收件人 | 收件人数统计 | 底部状态栏(成功前) | 统计 parseRecipients 后去重数量;保存配置与加载配置时会刷新 | 无 | [MailClientGUI.java:L1146-L1155](src/main/java/com/mailclient/MailClientGUI.java#L1146-L1155)
[MailClientGUI.java:L1166-L1177](src/main/java/com/mailclient/MailClientGUI.java#L1166-L1177) | | 收件人 | 刷新收件人数 | “刷新数量”按钮 | 手动触发收件人数重新统计 | 无 | [MailClientGUI.java:L976-L978](src/main/java/com/mailclient/MailClientGUI.java#L976-L978) | | 收件人 | 账户清洗(无效+去重) | “账户清洗”按钮 | 无效过滤+去重后回写到收件人文本框,并刷新收件人数 | 无 | [MailClientGUI.java:L979-L1007](src/main/java/com/mailclient/MailClientGUI.java#L979-L1007)
[MailClientGUI.java:L1179-L1199](src/main/java/com/mailclient/MailClientGUI.java#L1179-L1199) | | 收件人 | 起始位置高亮定位 | 起始位置 spinner 改变时 | 基于原文本 token 的 start/end 快照定位并高亮;同时滚动到对应位置;若越界则清除高亮 | 无 | [MailClientGUI.java:L1707-L1734](src/main/java/com/mailclient/MailClientGUI.java#L1707-L1734)
[MailClientGUI.java:L1810-L1849](src/main/java/com/mailclient/MailClientGUI.java#L1810-L1849) | | 内容编辑 | 主题编辑 | 右侧“主题” | 主题支持变量替换(发送时替换) | 保存到 config.properties | [MailClientGUI.java:L999-L1006](src/main/java/com/mailclient/MailClientGUI.java#L999-L1006)
[MailSender.java:L325-L327](src/main/java/com/mailclient/MailSender.java#L325-L327) | | 内容编辑 | HTML正文编辑 | 右侧“HTML正文” | 支持变量替换;若不含 `[MailSender.java:L328-L334](src/main/java/com/mailclient/MailSender.java#L328-L334) | | 内容编辑 | 导入HTML模板 | “导入HTML”按钮 | 读取 html/htm/txt,写入正文,并自动触发一次浏览器预览 | 无 | [MailClientGUI.java:L1966-L1982](src/main/java/com/mailclient/MailClientGUI.java#L1966-L1982) | | 内容编辑 | 浏览器预览 | “浏览器预览”按钮 | 将变量替换后的 HTML 写入 `preview.html` 并用 Desktop.browse 打开;预览时会做 `#eamil#` 与 `#url#` 的示例替换 | `~/.mail_send_box/preview.html` | [MailClientGUI.java:L1932-L1964](src/main/java/com/mailclient/MailClientGUI.java#L1932-L1964) | | 变量系统 | 变量配置 | 右侧“使用说明”下的变量区 | 格式 key=value;支持注释 #;值支持 random 指令(alpha/num/alnum/ja/jasay) | 保存到 config.properties | [MailClientGUI.java:L1663-L1688](src/main/java/com/mailclient/MailClientGUI.java#L1663-L1688)
[MailSender.java:L189-L225](src/main/java/com/mailclient/MailSender.java#L189-L225) | | 变量系统 | 随机变量生成(实现) | 发送时 | random:ja 生成假名;random:jasay 生成日文口语句子(模板组合上限 1000) | 无 | [MailSender.java:L227-L284](src/main/java/com/mailclient/MailSender.java#L227-L284)
[MailSender.java:L101-L176](src/main/java/com/mailclient/MailSender.java#L101-L176) | | URL 系统 | URL 列表展示与刷新按钮 | “URL配置”面板 | 点击“刷新域名”:UrlProvider.reload(),再从用户 url.txt 读取(不存在则用内置资源) | `~/.mail_send_box/url.txt` | [MailClientGUI.java:L2762-L2789](src/main/java/com/mailclient/MailClientGUI.java#L2762-L2789)
[UrlProvider.java:L57-L70](src/main/java/com/mailclient/UrlProvider.java#L57-L70) | | URL 系统 | 发送时随机URL替换 | MailSender.sendMail | 邮件正文中出现 `#url#` 时替换为 UrlProvider.getRandomUrl() | URL 来源:文件优先,其次资源 | [MailSender.java:L408-L411](src/main/java/com/mailclient/MailSender.java#L408-L411)
[UrlProvider.java:L61-L66](src/main/java/com/mailclient/UrlProvider.java#L61-L66) | | 发送控制 | 测试连接(单项SMTP) | “测试连接”按钮 | 使用左侧表单 SMTP + 当前选择的代理(可能来自多代理策略)做 testConnection | 无 | [MailClientGUI.java:L1207-L1240](src/main/java/com/mailclient/MailClientGUI.java#L1207-L1240)
[MailSender.java:L442-L473](src/main/java/com/mailclient/MailSender.java#L442-L473) | | 发送控制 | 测试所选SMTP | “测试”按钮(多SMTP区) | 对列表当前项构建 MailSender 并 testConnection | 无 | [MailClientGUI.java:L1242-L1266](src/main/java/com/mailclient/MailClientGUI.java#L1242-L1266) | | 发送控制 | 发送邮件(主流程) | “发送邮件”按钮 | 收件人去重;按起始位置截断;校验主题/正文/SMTP列表;构建 SendingContext(SMTP策略、代理策略、变量等);单线程或线程池发送;完成后更新 recipients.txt(成功移除、失败保留) | 成功/失败输出文件(按日);recipients.txt 会被更新 | [MailClientGUI.java:L1338-L1541](src/main/java/com/mailclient/MailClientGUI.java#L1338-L1541)
[MailClientGUI.java:L1736-L1792](src/main/java/com/mailclient/MailClientGUI.java#L1736-L1792) | | 发送控制 | 暂停/继续 | “暂停”按钮 | paused 标志+pauseLock wait/notify;继续时会从当前 startIndex 重新构建 sendQueue 与 SendingContext(会重置 badSmtps 与计数器) | 无 | [MailClientGUI.java:L1543-L1657](src/main/java/com/mailclient/MailClientGUI.java#L1543-L1657) | | 发送控制 | 停止 | “停止”按钮 | stopRequested=true、quotaExhausted=true、清队列、shutdownNow 线程池、interrupt 发送线程、UI 状态复位 | 无 | [MailClientGUI.java:L1571-L1611](src/main/java/com/mailclient/MailClientGUI.java#L1571-L1611) | | 发送策略 | SMTP 选择与故障切换 | 发送时 | eligibleConfigs=未被 bad 标记且未超配额;无可用时区分“都到上限” vs “都不可用(非网络异常)”并触发全局停止;每封邮件会记录使用的 SMTP | 日志会包含 SMTP/代理选择;停止原因写日志 | [MailClientGUI.java:L3167-L3213](src/main/java/com/mailclient/MailClientGUI.java#L3167-L3213)
[MailClientGUI.java:L3042-L3058](src/main/java/com/mailclient/MailClientGUI.java#L3042-L3058) | | 发送策略 | 网络异常重试(同SMTP但可换代理) | 发送时 | 同一个 picked SMTP 循环尝试;每次会重新 selectProxyForSend;网络异常指数退避等待(上限 8s);非网络异常返回失败并将 SMTP 加入 badSmtps | 无 | [MailClientGUI.java:L3117-L3165](src/main/java/com/mailclient/MailClientGUI.java#L3117-L3165)
[MailClientGUI.java:L3060-L3099](src/main/java/com/mailclient/MailClientGUI.java#L3060-L3099) | | 并发执行 | 单线程发送 | threadCount<=1 或收件人<=1 | 顺序 poll 队列;每封写成功/失败文件;UI 计数更新;startIndexSpinner 跟随进度 | 成功/失败文件追加写入 | [MailClientGUI.java:L3215-L3247](src/main/java/com/mailclient/MailClientGUI.java#L3215-L3247)
[MailClientGUI.java:L2047-L2077](src/main/java/com/mailclient/MailClientGUI.java#L2047-L2077) | | 并发执行 | 线程池并发发送 | threadCount>1 | 固定大小线程池;多 worker 竞争队列;每封发送结果立即写入文件;最终汇总 future | 同上 | [MailClientGUI.java:L3249-L3303](src/main/java/com/mailclient/MailClientGUI.java#L3249-L3303)
[MailClientGUI.java:L2047-L2077](src/main/java/com/mailclient/MailClientGUI.java#L2047-L2077) | | 日志与统计 | UI 发送日志 | sendMail/worker | 统一带时间戳;devMode 且有异常会打印堆栈到 UI 日志;“清空日志”按钮清空 | 无 | [MailClientGUI.java:L1034-L1051](src/main/java/com/mailclient/MailClientGUI.java#L1034-L1051)
[MailClientGUI.java:L2031-L2045](src/main/java/com/mailclient/MailClientGUI.java#L2031-L2045) | | 日志与统计 | 每日成功/失败文件 | 发送中持续写 | `yyyy-MM-dd-success.txt` 每行邮箱;`yyyy-MM-dd-fail.txt` 每行 `邮箱 -> 原因`,原因会压缩空白 | `~/.mail_send_box/*-success.txt` / `*-fail.txt` | [MailClientGUI.java:L2047-L2077](src/main/java/com/mailclient/MailClientGUI.java#L2047-L2077) | | 底部栏 | 状态/成功/失败/时间 | 底部状态栏 | 发送开始/结束会刷新时间;成功/失败计数实时刷新 | 无 | [MailClientGUI.java:L1117-L1137](src/main/java/com/mailclient/MailClientGUI.java#L1117-L1137)
[MailClientGUI.java:L1173-L1205](src/main/java/com/mailclient/MailClientGUI.java#L1173-L1205) | | JavaMail发送 | 收件人过滤(发送时) | MailSender.sendMail | 每次 sendMail 会将 recipients 过滤为有效 InternetAddress[];逐个收件人单独构造 MimeMessage 并 transport.sendMessage | 无 | [MailSender.java:L373-L433](src/main/java/com/mailclient/MailSender.java#L373-L433) | | JavaMail发送 | 代理应用 | MailSender.applyProxy | SOCKS5:mail.smtp.socks.*;HTTP:mail.smtp.proxy.* | 无 | [MailSender.java:L286-L312](src/main/java/com/mailclient/MailSender.java#L286-L312) | ### 已知细节/风险点(仅记录,不代表已修复) - 帮助文案写 `#email#`,但实际代码使用 `#eamil#`(预览和发送均如此):[MailSender.java:L435-L436](src/main/java/com/mailclient/MailSender.java#L435-L436)、[MailClientGUI.java:L1944-L1946](src/main/java/com/mailclient/MailClientGUI.java#L1944-L1946) - UrlProvider 资源读取存在潜在 NPE:`is == null` 的判断在 `new InputStreamReader(is, ...)` 之后:[UrlProvider.java:L28-L40](src/main/java/com/mailclient/UrlProvider.java#L28-L40) - HTTP 代理“测试连通性”只测连到代理端口,不测代理到 SMTP 的 CONNECT/认证链路:[MailClientGUI.java:L2583-L2635](src/main/java/com/mailclient/MailClientGUI.java#L2583-L2635)、[MailSender.java:L302-L311](src/main/java/com/mailclient/MailSender.java#L302-L311) ## 系统要求 - Java 17 或更高版本 - Maven 3.6 或更高版本 ## 编译和运行 ### 使用Maven编译 ```bash mvn clean compile ``` ### 打包成JAR文件 ```bash mvn clean package ``` ### 运行程序 ```bash # 方式1:使用Maven运行 mvn exec:java -Dexec.mainClass="com.mailclient.MailClientGUI" # 方式2:运行打包后的JAR java -jar target/mail-send-box-1.0.0.jar ``` ## 使用说明 ### 1. 配置SMTP服务器 在左侧"SMTP服务器配置"区域填写: - **SMTP主机**:如 `smtp.qq.com`、`smtp.gmail.com` 等 - **SMTP端口**:常用端口有 25、465(SSL)、587(TLS) - **用户名/邮箱**:您的邮箱地址 - **密码/授权码**:邮箱密码或授权码(部分邮箱需要使用授权码) - **启用SSL/TLS**:根据您的邮箱服务商要求选择 #### 常见邮箱SMTP配置 **QQ邮箱:** - SMTP主机:smtp.qq.com - SMTP端口:587 - 启用TLS:是 - 需要开启SMTP服务并获取授权码 **Gmail:** - SMTP主机:smtp.gmail.com - SMTP端口:587 - 启用TLS:是 **163邮箱:** - SMTP主机:smtp.163.com - SMTP端口:25 或 465(SSL) - 启用SSL:是(如果使用465端口) ### 2. 填写收件人 在"收件人"区域填写收件人邮箱,可多行或使用逗号、分号分隔;也可点击“导入收件人列表”从文件批量导入。 ### 3. 设置发件人显示名(可选) 在“发件人显示名”中填写需要展示的名称(支持变量)。 ### 4. 编写邮件主题 在"主题"输入框中填写邮件主题,支持变量替换。 **示例:** ``` 欢迎 ${name} 使用我们的服务! ``` ### 5. 编写HTML正文 在"HTML正文"文本框中编写HTML格式的邮件正文,支持变量替换。 **示例:** ```html

欢迎, ${name}!

今天是 ${date}

${content}


此邮件由系统自动发送

``` ### 6. 配置变量 在"变量配置"区域配置变量值,格式为:`变量名=变量值`,每行一个。 **示例:** ``` name=张三 date=2024-01-15 content=这是一封测试邮件,感谢您的使用! ``` ### 7. 域名列表(URL配置)与刷新 - 右侧“变量配置”下方有“URL配置 (url.txt,每行一个)”。 - 列表来源优先级:`~/.mail_send_box/url.txt`(缓存文件) > 内置资源 `src/main/resources/url.txt`。 - 点击“刷新域名”按钮会重新加载列表(从缓存文件读取;若不存在则回退资源),并更新右侧列表展示。 - 邮件正文中使用占位符 `#url#` 时,每封邮件会使用当前内存列表中的随机URL(`UrlProvider.getRandomUrl()`)。 ### 7. 代理配置(可选) 在“代理配置”中可开启 SOCKS5 或 HTTP 代理,填写主机和端口后生效。 ### 8. 测试连接 点击"测试连接"按钮,验证SMTP配置是否正确。 ### 9. 并发与发送日志 - “并发线程数”可设置 1-50,>1 时按收件人并行发送 - 发送后右侧“发送日志”展示每个收件人成功/失败详情,并统计成功/失败数 ### 11. 成功/失败日志文件(实时写入) - 路径:`~/.mail_send_box/` - 文件:`yyyy-MM-dd-success.txt`(成功邮箱,一行一个) - 文件:`yyyy-MM-dd-fail.txt`(失败邮箱与原因,每行:`email -> reason`) - 写入时机:每个收件人发送完成后立即追加写入(顺序与并发模式均实时)。 ### 10. 发送邮件 点击"发送邮件"按钮发送邮件。发送成功后会有提示。 ## 变量使用说明 ### 变量格式 在主题和正文中使用 `${变量名}` 格式来引用变量。 **示例:** - 主题:`${name},您的订单已确认` - 正文:`

亲爱的 ${name},您的订单号是 ${orderId}

` ### 变量配置 在"变量配置"区域配置变量值: - 格式:`变量名=变量值` - 每行一个变量 - 支持空行和注释(以 `#` 开头的行会被忽略) ### 随机变量 变量值支持随机生成指令(填在右侧变量配置中),格式: - `random:alpha:长度` 只含字母 - `random:num:长度` 只含数字 - `random:alnum:长度` 字母+数字 示例: ``` token=random:alnum:12 code=random:num:6 nickname=random:alpha:8 ``` **示例:** ``` # 用户信息 name=李四 email=user@example.com # 订单信息 orderId=ORD-2024-001 amount=99.99 ``` ## 项目结构 ``` mail_send_box/ ├── pom.xml ├── README.md └── src/ └── main/ ├── resources/ │ └── url.txt └── java/ └── com/ └── mailclient/ ├── MailClientGUI.java ├── MailSender.java ├── UrlProvider.java ├── SmtpConfig.java ├── SmtpSelector.java ├── ProxyConfig.java └── ProxySelector.java ``` ## 技术栈 - **Java Swing**:GUI界面框架 - **JavaMail API**:邮件发送功能 - **Maven**:项目管理和依赖管理 ## 注意事项 1. 本项目仅供学习,违法后果自负;请遵守当地法律法规 2. 部分邮箱服务商(如QQ邮箱、Gmail)需要使用授权码而不是登录密码 3. 确保网络连接正常,能够访问SMTP服务器;如有需要请正确设置代理 4. HTML正文必须符合HTML格式规范 5. 变量名区分大小写;未配置的变量会被替换为空字符串 6. 并发发送请合理设置线程数,避免触发服务商限流 ## 许可证 / 免责声明 本项目仅供学习和个人使用,禁止用于任何非法或滥用场景,使用者自行承担由此产生的全部后果。