0

0

Java邮件发送 Java使用SMTP协议发送邮件教程

雪夜

雪夜

发布时间:2025-07-19 17:15:02

|

538人浏览过

|

来源于php中文网

原创

使用javamail api发送邮件的核心步骤包括引入依赖、配置邮件服务器属性、创建session对象、构建邮件内容并发送。2. 安全配置主要包括启用ssl/tls加密传输和smtp认证,使用授权码替代邮箱密码以提升安全性。3. 处理附件和html内容需使用mimemultipart和mimebodypart组合邮件内容,分别设置html正文和附件。4. 邮件发送失败常见原因包括认证失败、连接问题、ssl/tls握手失败、邮件内容格式问题及服务器限流,可通过开启调试日志、检查配置、验证文件路径等方式排查。

Java邮件发送 Java使用SMTP协议发送邮件教程

在Java里想发邮件,最直接且标准的路子就是用JavaMail API,它底层会帮你搞定SMTP(Simple Mail Transfer Protocol)协议的那些事儿。简单说,就是你告诉JavaMail邮件内容、收件人、发件人,以及连接哪个邮件服务器,它就能帮你把邮件送出去。

Java邮件发送 Java使用SMTP协议发送邮件教程

要用JavaMail API发邮件,你得先把它引入到你的项目里。Maven用户可以加这个依赖:

<dependency>
    <groupId>com.sun.mail</groupId>
    <artifactId>jakarta.mail</artifactId>
    <version>2.0.1</version> <!-- 或者更高版本 -->
</dependency>

或者,如果你还在用老一点的javax.mail,那可能是:

立即学习Java免费学习笔记(深入)”;

Java邮件发送 Java使用SMTP协议发送邮件教程
<dependency>
    <groupId>javax.mail</groupId>
    <artifactId>mail</artifactId>
    <version>1.4.7</version> <!-- 或者你用的版本 -->
</dependency>

接下来就是核心的发送逻辑了。这块儿其实并不复杂,主要就是配置邮件服务器的信息,然后构造邮件内容,最后发送。

import jakarta.mail.*;
import jakarta.mail.internet.*;
import java.util.Properties;

public class EmailSender {

    public static void sendEmail(String to, String from, String subject, String body,
                                 String host, String port, final String username, final String password) throws MessagingException {

        // 1. 配置邮件服务器属性
        Properties props = new Properties();
        props.put("mail.smtp.host", host);
        props.put("mail.smtp.port", port);
        props.put("mail.smtp.auth", "true"); // 需要认证
        props.put("mail.smtp.ssl.enable", "true"); // 启用SSL/TLS加密
        props.put("mail.smtp.socketFactory.class", "jakarta.net.ssl.SSLSocketFactory"); // 指定SSL工厂
        props.put("mail.smtp.socketFactory.fallback", "false"); // 不允许回退
        props.put("mail.smtp.socketFactory.port", port); // 指定SSL端口

        // 2. 创建Session对象,用于与邮件服务器交互
        Session session = Session.getInstance(props, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }
        });

        // 开启调试模式,可以看到更详细的交互日志
        // session.setDebug(true);

        try {
            // 3. 创建MimeMessage对象,代表一封邮件
            MimeMessage message = new MimeMessage(session);

            // 设置发件人
            message.setFrom(new InternetAddress(from));

            // 设置收件人
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));

            // 设置邮件主题
            message.setSubject(subject);

            // 设置邮件内容
            message.setText(body); // 默认是纯文本

            // 4. 发送邮件
            Transport.send(message);

            System.out.println("邮件发送成功!");

        } catch (MessagingException e) {
            System.err.println("邮件发送失败:" + e.getMessage());
            throw e; // 抛出异常以便上层处理
        }
    }

    public static void main(String[] args) {
        // 示例用法:请替换为你的真实信息
        String to = "recipient@example.com"; // 收件人邮箱
        String from = "your_email@example.com"; // 发件人邮箱
        String subject = "测试邮件主题";
        String body = "这是一封通过JavaMail发送的测试邮件。";

        // 不同的邮件服务商,SMTP服务器地址和端口可能不同
        // 比如:
        // QQ邮箱:smtp.qq.com, 465 (SSL)
        // 163邮箱:smtp.163.com, 465 (SSL)
        // Gmail:smtp.gmail.com, 465 (SSL) 或 587 (TLS)
        String host = "smtp.qq.com"; // 邮件服务器主机
        String port = "465"; // 邮件服务器端口,SSL通常是465

        // 你的邮箱账号和授权码(不是邮箱密码,需要去邮箱设置里开启SMTP服务并获取)
        String username = "your_email@example.com";
        String password = "your_authorization_code"; // 授权码

        try {
            sendEmail(to, from, subject, body, host, port, username, password);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }
}

这段代码的核心逻辑就是:配置连接参数,创建会话,构建邮件,然后发送。我个人觉得,这里面最容易出错的,反而不是代码逻辑本身,而是那些邮件服务器的配置,比如端口、是否需要SSL/TLS、以及那个“授权码”的问题。很多新手会直接拿邮箱密码去试,结果总是失败,因为现在大部分邮件服务商都要求用授权码来替代密码进行第三方客户端登录。

Java邮件发送 Java使用SMTP协议发送邮件教程

Java邮件发送中常见的安全配置有哪些?

在JavaMail发送邮件时,安全性绝对是绕不过去的话题。毕竟邮件里可能包含敏感信息,而且登录邮件服务器也需要凭证。最常见的安全配置主要围绕加密和认证展开。

首先是加密传输。SMTP协议本身是明文传输的,这在信息安全方面是不能接受的。所以我们通常会用到SSL(Secure Sockets Layer)或TLS(Transport Layer Security)来加密通信

  • SSL/TLS直连 (通常是端口465):这是最常见的配置方式,尤其对于那些要求严格加密的邮件服务商。在Properties里,你需要设置mail.smtp.ssl.enabletrue,并且通常端口是465。我上面代码示例用的就是这种方式。它意味着在连接建立之初,就会进行SSL握手,整个通信通道都是加密的。
    props.put("mail.smtp.ssl.enable", "true");
    props.put("mail.smtp.socketFactory.class", "jakarta.net.ssl.SSLSocketFactory");
    props.put("mail.smtp.socketFactory.fallback", "false");
    props.put("mail.smtp.socketFactory.port", "465");
  • STARTTLS (通常是端口587):另一种常见的加密方式。它是在建立一个普通的、未加密的连接后,通过发送STARTTLS命令来升级连接为加密模式。如果你的邮件服务器支持,并且端口是587,那么可以这样配置:
    props.put("mail.smtp.starttls.enable", "true");
    props.put("mail.smtp.port", "587");
    // 此时 mail.smtp.ssl.enable 不再需要设置为 true,或者设置为 false

    选择哪种取决于你的邮件服务商支持哪种方式,或者推荐哪种。我个人倾向于优先尝试SSL直连(465端口),因为它更直接。

其次是身份认证。邮件服务器需要知道是谁在尝试发送邮件,以防止垃圾邮件和未经授权的使用。

  • SMTP认证 (SMTP Authentication):这是最基本的认证方式,通过用户名和密码(或授权码)来验证发件人身份。在Properties里,设置mail.smtp.authtrue
    props.put("mail.smtp.auth", "true");

    然后,在创建Session时,通过Authenticator提供你的用户名和密码(授权码)。这是我在示例代码中已经展示的。

一个常被忽略但非常重要的点是授权码。现在很多大型邮件服务商(如QQ邮箱、163邮箱、Gmail等)为了账户安全,不再允许第三方客户端直接使用你的邮箱登录密码进行SMTP认证。它们会要求你到邮箱设置里生成一个“授权码”或“客户端专用密码”,这个码就是你用来代替登录密码进行SMTP认证的。如果你遇到认证失败的问题,第一步就应该检查是不是用了错误的密码,或者压根没用授权码。

最后,一些更高级的安全配置可能包括:

  • 严格的主机名验证:确保连接到的SMTP服务器是预期的服务器,而不是中间人攻击。这通常是Java默认处理的,但如果遇到证书问题,可能需要检查。
  • 信任证书:如果你使用的是自签名证书或企业内部的证书,可能需要将这些证书添加到Java的信任库(cacerts)中,否则会报SSL握手失败的错误。不过对于公共邮件服务商,通常不需要手动配置。

总的来说,安全配置的核心就是“加密”和“认证”,确保数据在传输过程中不被窃听,并且只有授权的用户才能发送邮件。

如何处理Java邮件发送中的附件和HTML内容?

发送纯文本邮件固然简单,但在实际应用中,我们经常需要发送带有格式的HTML邮件,或者夹带文件附件。JavaMail API在这方面提供了非常灵活的支持,主要通过MimeMultipartMimeBodyPart这两个类来实现。

发送HTML内容:

Tome
Tome

先进的AI智能PPT制作工具

下载

发送HTML邮件其实比纯文本多一步,就是告诉邮件客户端你发送的是HTML而不是普通文本。这通过设置Content-Type头部来实现。

// ... (前面的Properties和Session配置不变)

MimeMessage message = new MimeMessage(session);
// ... 设置发件人、收件人、主题

// 设置邮件内容为HTML
message.setContent("<h1>你好!</h1><p>这是一封<b>HTML</b>格式的测试邮件。</p>", "text/html; charset=utf-8");

// ... Transport.send(message);

就这么简单!setContent方法的第二个参数就是用来指定内容类型的,text/html表示HTML格式,charset=utf-8则确保中文等字符正确显示。

发送附件:

发送附件稍微复杂一点,因为它涉及到将邮件内容和附件内容组合在一起。这需要用到MimeMultipart(多部分邮件内容)和MimeBodyPart(邮件的每个部分)。

一个典型的带附件的邮件结构是:一个MimeMultipart作为邮件的主体,它里面包含两个或更多MimeBodyPart。其中一个MimeBodyPart是邮件的文本内容(可以是纯文本或HTML),另一个或多个MimeBodyPart是附件。

import jakarta.activation.DataHandler;
import jakarta.activation.FileDataSource;
// ... 其他导入

// ... (前面的Properties和Session配置不变)

MimeMessage message = new MimeMessage(session);
// ... 设置发件人、收件人、主题

// 1. 创建MimeMultipart对象,用于组合邮件的各个部分
MimeMultipart multipart = new MimeMultipart();

// 2. 创建邮件文本部分
MimeBodyPart textPart = new MimeBodyPart();
textPart.setContent("<h1>你好!</h1><p>这是一封带附件的HTML邮件。</p>", "text/html; charset=utf-8");
multipart.addBodyPart(textPart); // 将文本部分添加到multipart中

// 3. 创建附件部分
String filePath = "path/to/your/file.pdf"; // 附件文件的路径
FileDataSource source = new FileDataSource(filePath); // 创建文件数据源
MimeBodyPart attachmentPart = new MimeBodyPart();
attachmentPart.setDataHandler(new DataHandler(source)); // 设置数据处理器
attachmentPart.setFileName(source.getName()); // 设置附件的文件名,邮件客户端会显示这个名字
multipart.addBodyPart(attachmentPart); // 将附件部分添加到multipart中

// 如果有多个附件,可以重复步骤3

// 4. 将multipart设置为邮件的内容
message.setContent(multipart);

// ... Transport.send(message);

这里的关键是MimeMultipart,它像一个容器,可以装载不同的MimeBodyPartMimeBodyPart可以代表文本内容、HTML内容,也可以代表附件。对于附件,我们用FileDataSource来包装文件,然后通过DataHandler设置给MimeBodyPartsetFileName方法则决定了附件在邮件客户端中显示的名字。

需要注意的是,当邮件既有文本/HTML内容又有附件时,邮件的Content-Type通常会被自动设置为multipart/mixed。如果邮件是HTML和纯文本的“多替代”内容(即提供纯文本作为HTML的备用),则会是multipart/alternative。JavaMail API会根据你添加MimeBodyPart的方式智能地处理这些。

我个人觉得,处理附件这块儿最容易犯的错误就是忘了设置setFileName,或者路径不对导致文件找不到。另外,对于非常大的附件,直接在内存中处理可能会导致内存溢出,这时可以考虑流式处理或者使用专门的文件上传服务,但对于普通大小的附件,上述方法足够了。

Java邮件发送失败的常见原因及排查方法?

邮件发送失败是开发中经常遇到的问题,而且原因五花八门。我经历过不少次,每次排查都像侦探破案。不过,总结下来,常见的失败原因也就那么几类,掌握了排查方法,就能事半功倍。

  1. 认证失败 (Authentication Failed)

    • 原因:用户名或密码(授权码)错误是最常见的原因。邮件服务商通常要求使用授权码而非登录密码进行第三方客户端SMTP认证。
    • 排查
      • 检查授权码:去你的邮箱设置里,确认SMTP服务已开启,并获取最新的授权码。
      • 用户名:确认发件邮箱地址是否填写正确。
      • session.setDebug(true):这是我的首选调试工具。在创建Session对象后,调用session.setDebug(true),JavaMail会在控制台输出详细的SMTP交互日志。如果认证失败,你会看到类似535 Authentication Failed550 Authentication Required的错误信息。
  2. 连接问题 (Connection Issues)

    • 原因:SMTP服务器地址或端口错误;网络不通(比如防火墙阻止了连接);服务器暂时不可用。
    • 排查
      • 主机和端口:仔细核对mail.smtp.hostmail.smtp.port。不同服务商、不同加密方式(SSL/TLS)端口可能不同(如465、587、25)。
      • 网络连通性:在你的服务器或本地机器上,尝试ping邮件服务器地址,看是否能通。更进一步,可以使用telnet smtp.your-email.com 465(或对应端口)来测试端口是否开放且可连接。如果telnet连接不上,那基本就是网络或防火墙问题了。
      • 服务器状态:有时候邮件服务器本身可能在维护或临时故障。
  3. SSL/TLS握手失败 (SSL/TLS Handshake Failure)

    • 原因:SSL/TLS配置不正确(比如ssl.enablestarttls.enable混淆);Java环境缺少必要的证书;服务器证书过期或不被信任。
    • 排查
      • 配置检查:确认mail.smtp.ssl.enablemail.smtp.starttls.enable是否与你使用的端口和服务器要求匹配。不要同时开启两者,或者配置冲突。
      • session.setDebug(true):同样,调试日志会显示SSL握手过程中的详细错误,比如PKIX path building failed通常表示证书信任问题。
      • Java信任库:对于公共邮件服务商,通常不需要手动配置。但如果遇到证书问题,可能需要检查Java的cacerts文件是否包含必要的根证书。
  4. 邮件内容或格式问题

    • 原因:发件人或收件人地址格式不正确;邮件内容过大;附件路径错误或文件不存在。
    • 排查
      • 地址格式:确保InternetAddress.parse()传入的地址是有效的邮箱格式。
      • 附件问题:检查附件文件路径是否正确,文件是否存在且可读。
      • 日志:通常这类问题不会直接导致SMTP连接失败,而是在Transport.send()时抛出MessagingException。错误信息会提示具体的问题。
  5. 服务器拒绝发送

    • 原因:发件人被列入黑名单;邮件内容被判定为垃圾邮件;发送频率过高触发了服务器的限流。
    • 排查
      • 检查邮箱状态:登录发件邮箱,看是否有异常登录提醒或发送异常通知。
      • 邮件内容:尝试发送一个非常简单的纯文本邮件,排除内容被判定为垃圾邮件的可能性。
      • 发送频率:如果是批量发送,考虑增加发送间隔,或联系邮件服务商了解其发送策略和限额。

我个人最喜欢用session.setDebug(true),它能提供最直接的线索。每次遇到邮件发送问题,我都是先开调试模式,看看SMTP服务器到底说了什么,然后根据错误码和信息去定位问题。很多时候,错误信息里已经把原因说得很清楚了,只是我们没仔细看。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Java Maven专题
Java Maven专题

本专题聚焦 Java 主流构建工具 Maven 的学习与应用,系统讲解项目结构、依赖管理、插件使用、生命周期与多模块项目配置。通过企业管理系统、Web 应用与微服务项目实战,帮助学员全面掌握 Maven 在 Java 项目构建与团队协作中的核心技能。

0

2025.09.15

session失效的原因
session失效的原因

session失效的原因有会话超时、会话数量限制、会话完整性检查、服务器重启、浏览器或设备问题等等。详细介绍:1、会话超时:服务器为Session设置了一个默认的超时时间,当用户在一段时间内没有与服务器交互时,Session将自动失效;2、会话数量限制:服务器为每个用户的Session数量设置了一个限制,当用户创建的Session数量超过这个限制时,最新的会覆盖最早的等等。

336

2023.10.17

session失效解决方法
session失效解决方法

session失效通常是由于 session 的生存时间过期或者服务器关闭导致的。其解决办法:1、延长session的生存时间;2、使用持久化存储;3、使用cookie;4、异步更新session;5、使用会话管理中间件。

776

2023.10.18

cookie与session的区别
cookie与session的区别

本专题整合了cookie与session的区别和使用方法等相关内容,阅读专题下面的文章了解更详细的内容。

97

2025.08.19

SSL检测工具介绍
SSL检测工具介绍

SSL检测工具有SSL Labs、SSL Check、SSL Server Test、SSLMate、SSL/TLS Analyzer等。详细介绍:1、SSL Labs是一个由Qualys提供的在线SSL检测工具,可以评估服务器证书的部署情况、加密套件、协议支持等方面的安全性,它提供了一个详细的报告,包括证书的颁发者、有效期、安全性配置等;2、SSL Check等等。

355

2023.10.20

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

69

2026.03.11

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

37

2026.03.10

Kotlin Android模块化架构与组件化开发实践
Kotlin Android模块化架构与组件化开发实践

本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

82

2026.03.09

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

97

2026.03.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 0.9万人学习

PHP入门速学(台湾同胞版)
PHP入门速学(台湾同胞版)

共10课时 | 1.3万人学习

韩顺平 2016年 最新PHP基础视频教程
韩顺平 2016年 最新PHP基础视频教程

共47课时 | 10.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号