利用java实现发送邮件

利用java实现发送邮件电子邮件的应用非常广泛,常见的如在某网站注册了一个账户,自动发送一封激活邮件,通过邮件找回密码,自动批量发送活动信息等。很显然这些应用不可能和我们自己平时发邮件一样,先打开浏览器,登录邮箱,创建邮件再发送。本文将简单介绍如何通过Java代码来创建电子邮件,并连接邮件服务器发送邮件。电子邮件协议电子邮件在网络中传输和网页一样需要遵从特定的协议,常用的电子邮件协议包括SMTP,POP3,IMA…

大家好,又见面了,我是你们的朋友全栈君。

电子邮件的应用非常广泛,常见的如在某网站注册了一个账户,自动发送一封激活邮件,通过邮件找回密码,自动批量发送活动信息等。很显然这些应用不可能和我们自己平时发邮件一样,先打开浏览器,登录邮箱,创建邮件再发送。本文将简单介绍如何通过 Java 代码来创建电子邮件,并连接邮件服务器发送邮件。

电子邮件协议
电子邮件在网络中传输和网页一样需要遵从特定的协议,常用的电子邮件协议包括 SMTP,POP3,IMAP。其中邮件的创建和发送只需要用到 SMTP协议,所以本文也只会涉及到SMTP协议。SMTP 是 Simple Mail Transfer Protocol 的简称,即简单邮件传输协议。
JavaMail
我们平时通过 Java 代码打开一个 http 网页链接时,通常可以使用已经对 http 协议封装好的 HttpURLConnection 类来快速地实现。Java 官方也提供了对电子邮件协议封装的 Java 类库,就是JavaMail,但并没有包含到标准的 JDK 中,需要我们自己去官方下载,这里我从 JavaEE 官方的 Github 仓库下载。
JavaMail 下载地址:https://github.com/javaee/javamail/releases
最新的版本是 1.6.0 ,包含了 SMTP, IMAP, 和 POP3 协议的实现:
利用java实现发送邮件
如果是mvn项目的话,我们只需要添加依赖即可
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.5.0-b01</version>
</dependency>
创建一封简单的电子邮件
邮件创建步骤:
1. 创建一个邮件对象(MimeMessage);
2. 设置发件人,收件人,可选增加多个收件人,抄送人,密送人;
3. 设置邮件的主题(标题);
4. 设置邮件的正文(内容);
5. 设置显示的发送时间;
6. 保存到本地。
代码如下:

 

public class TestMail {
    public static void main(String[] args) throws Exception {
        // 1. 创建一封邮件
        Properties props = new Properties();                // 用于连接邮件服务器的参数配置(发送邮件时才需要用到)
        Session session= Session.getInstance(props);        // 根据参数配置,创建会话对象(为了发送邮件准备的)
        MimeMessage message = new MimeMessage(session);     // 创建邮件对象

        /*
         * 也可以根据已有的eml邮件文件创建 MimeMessage 对象
         * MimeMessage message = new MimeMessage(session, new FileInputStream("myEmail.eml"));
         */

        // 2. From: 发件人
        //    其中 InternetAddress 的三个参数分别为: 邮箱, 显示的昵称(只用于显示, 没有特别的要求), 昵称的字符集编码
        //    真正要发送时, 邮箱必须是真实有效的邮箱。
        message.setFrom(new InternetAddress("email@send.com", "USER_AA", "UTF-8"));

        // 3. To: 收件人
        message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress("cc@receive.com", "USER_CC", "UTF-8"));
        //    To: 增加收件人(可选)
        message.addRecipient(MimeMessage.RecipientType.TO, new InternetAddress("dd@receive.com", "USER_DD", "UTF-8"));
        //    Cc: 抄送(可选)
        message.setRecipient(MimeMessage.RecipientType.CC, new InternetAddress("ee@receive.com", "USER_EE", "UTF-8"));
        //    Bcc: 密送(可选)
        message.setRecipient(MimeMessage.RecipientType.BCC, new InternetAddress("ff@receive.com", "USER_FF", "UTF-8"));

        // 4. Subject: 邮件主题
        message.setSubject("邮件主题", "UTF-8");

        // 5. Content: 邮件正文(可以使用html标签)
        message.setContent("这是邮件正文", "text/html;charset=UTF-8");

        // 6. 设置显示的发件时间
        message.setSentDate(new Date());

        // 7. 保存前面的设置
        message.saveChanges();

        // 8. 将该邮件保存到本地
        OutputStream out = new FileOutputStream("myEmail.eml");
        message.writeTo(out);
        out.flush();
        out.close();
    }
}

保存的 myEmail.eml 可以使用邮件客户端打开查看,实际上就是一堆符合SMTP协议格式的文本(内容使用base64进行了编码),也可用记事本打开,如下所示:
利用java实现发送邮件
发送电子邮件
发送邮件首先需要有一个邮箱账号和密码,本文以网易126邮箱为例,邮箱账号必须要开启 SMTP 服务,在浏览器网页登录邮箱后一般在邮箱的“设置”选项中可以开启,并记下邮箱的 SMTP 服务器地址,如下所示(其他邮箱大同小异):
利用java实现发送邮件
代码实现:

 

public class SendMail {
    // 发件人的 邮箱 和 密码(替换为自己的邮箱和密码)
    // PS: 某些邮箱服务器为了增加邮箱本身密码的安全性,给 SMTP 客户端设置了独立密码(有的邮箱称为“授权码”),
    //     对于开启了独立密码的邮箱, 这里的邮箱密码必需使用这个独立密码(授权码)。
    public static String myEmailAccount = "xxxxxxx@126.com";
    public static String myEmailPassword = "xxxxxxxx";

    // 发件人邮箱的 SMTP 服务器地址, 必须准确, 不同邮件服务器地址不同, 一般(只是一般, 绝非绝对)格式为: smtp.xxx.com
    // 网易126邮箱的 SMTP 服务器地址为: smtp.126.com
    public static String myEmailSMTPHost = "smtp.126.com";

    // 收件人邮箱(替换为自己知道的有效邮箱)
    public static String receiveMailAccount = "xxxxxx@qq.com";

    public static void main(String[] args) throws Exception {
        // 1. 创建参数配置, 用于连接邮件服务器的参数配置
        Properties props = new Properties();                    // 参数配置
        props.setProperty("mail.transport.protocol", "smtp");   // 使用的协议(JavaMail规范要求)
        props.setProperty("mail.smtp.host", myEmailSMTPHost);   // 发件人的邮箱的 SMTP 服务器地址
        props.setProperty("mail.smtp.auth", "true");            // 需要请求认证

        // PS: 某些邮箱服务器要求 SMTP 连接需要使用 SSL 安全认证 (为了提高安全性, 邮箱支持SSL连接, 也可以自己开启),
        //     如果无法连接邮件服务器, 仔细查看控制台打印的 log, 如果有有类似 “连接失败, 要求 SSL 安全连接” 等错误,
        //     取消下面 /* ... */ 之间的注释代码, 开启 SSL 安全连接。
        /*
        // SMTP 服务器的端口 (非 SSL 连接的端口一般默认为 25, 可以不添加, 如果开启了 SSL 连接,
        //                  需要改为对应邮箱的 SMTP 服务器的端口, 具体可查看对应邮箱服务的帮助,
        //                  QQ邮箱的SMTP(SLL)端口为465或587, 其他邮箱自行去查看)
        final String smtpPort = "465";
        props.setProperty("mail.smtp.port", smtpPort);
        props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.setProperty("mail.smtp.socketFactory.fallback", "false");
        props.setProperty("mail.smtp.socketFactory.port", smtpPort);
        */

        // 2. 根据配置创建会话对象, 用于和邮件服务器交互
        Session session = Session.getInstance(props);
        // 设置为debug模式, 可以查看详细的发送 log
        session.setDebug(true);

        // 3. 创建一封邮件
        MimeMessage message = createMimeMessage(session, myEmailAccount, receiveMailAccount);

        // 4. 根据 Session 获取邮件传输对象
        Transport transport = session.getTransport();

        // 5. 使用 邮箱账号 和 密码 连接邮件服务器, 这里认证的邮箱必须与 message 中的发件人邮箱一致, 否则报错
        //
        //    PS_01: 如果连接服务器失败, 都会在控制台输出相应失败原因的log。
        //    仔细查看失败原因, 有些邮箱服务器会返回错误码或查看错误类型的链接,
        //    根据给出的错误类型到对应邮件服务器的帮助网站上查看具体失败原因。
        //
        //    PS_02: 连接失败的原因通常为以下几点, 仔细检查代码:
        //           (1) 邮箱没有开启 SMTP 服务;
        //           (2) 邮箱密码错误, 例如某些邮箱开启了独立密码;
        //           (3) 邮箱服务器要求必须要使用 SSL 安全连接;
        //           (4) 请求过于频繁或其他原因, 被邮件服务器拒绝服务;
        //           (5) 如果以上几点都确定无误, 到邮件服务器网站查找帮助。
        //
        transport.connect(myEmailAccount, myEmailPassword);

        // 6. 发送邮件, 发到所有的收件地址, message.getAllRecipients() 获取到的是在创建邮件对象时添加的所有收件人, 抄送人, 密送人
        transport.sendMessage(message, message.getAllRecipients());

        // 7. 关闭连接
        transport.close();
    }

    /**
     * 创建一封只包含文本的简单邮件
     *
     * @param session     和服务器交互的会话
     * @param sendMail    发件人邮箱
     * @param receiveMail 收件人邮箱
     * @return
     * @throws Exception
     */
    public static MimeMessage createMimeMessage(Session session, String sendMail, String receiveMail) throws Exception {
        // 1. 创建一封邮件
        MimeMessage message = new MimeMessage(session);

        // 2. From: 发件人
        message.setFrom(new InternetAddress(sendMail, "昵称", "UTF-8"));

        // 3. To: 收件人(可以增加多个收件人、抄送、密送)
        message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(receiveMail, "XX用户", "UTF-8"));

        // 4. Subject: 邮件主题
        message.setSubject("主题", "UTF-8");

        // 5. Content: 邮件正文(可以使用html标签)
        message.setContent("邮件正文", "text/html;charset=UTF-8");
            // 6. 设置发件时间
        message.setSentDate(new Date());

        // 7. 保存设置
        message.saveChanges();

        return message;
    }
}

下面我们对我们的代码解析一下:
1、对应用程序配置邮件会话
javax.mail.Session保存邮件系统的配置属性和提供用户验证的信息,发送email首先要获取session对象。
(1)Session.getInstance(java.util.Properties)获取非共享的session对象
(2)Session.getDefaultInstance(java.utilProperties)获取共享的session对象
两者都必须建立Properties prop=new Properties()对象;
注意:一般对单用户桌面应用程序使用共享Session对象。
用SMTP协议发送Email时通常要设置mail.smtp.host(mail.protocol.host协议特定邮件服务器名)属性。

prop.put("mail.smtp.host","smtp.mailServer.com");
Session mailSession=Session.getInstance(prop);

注意:在真正使用创建的过程中,往往会让我们验证密码,这是我们要写一个密码验证类。javax.mail.Authenticator是一个抽象类,我们要写MyAuthenticator的密码验证类,该类继承Authenticator实现:

protected PasswordAuthentication getPasswordAuthentication(){
return new PasswordAuthentication(String userName, String password);
}

这时我们创建Session对象:
Session mailSession=Session.getInstance(prop,new MyAuthenticator(userName,Password));
并且要设置使用验证:prop.put(“mail.smtp.auth”,”true”);
使用 STARTTLS安全连接:prop.put(“mail.smtp.starttls.enable”,”true”);
2、配置邮件会话之后,要编写消息
要编写消息就要生成javax.mail.Message子类的实例或对Internet邮件使用javax.mail.interet.MimeMessage类。
(1)建立MimeMessage对象
MimeMessage扩展抽象的Message类,构造MimeMessage对象:
MimeMessage message=new MimeMessage(mailSession);
(2)消息发送者、日期、主题

message.setFrom(Address theSender);
message.setSentDate(java.util.Date theDate);
message.setSubject(String theSubject);

(3)设置消息的接受者与发送者(寻址接收)

setRecipient(Message.RecipientType type , Address theAddress);
setRecipients(Message.RecipientType type , Address[] theAddress);
addRecipient(Message.RecipientType type , Address theAddress);
addRecipients(Message.RecipientType type,Address[] theAddress);

方法都可以指定接受者类型,但是一般用后两个,这样可以避免意外的替换或者覆盖接受者名单。定义接受者类型:
Message.RecipientType.TO:消息接受者
Message.RecipientType.CC:消息抄送者
Message.RecipientType.BCC:匿名抄送接收者(其他接受者看不到这个接受者的姓名和地址)
(4)设置消息内容
JavaMail基于JavaBean Activation FrameWork(JAF),JAF可以构造文本消息也可以支持附件。
设置消息内容时,要提供消息的内容类型—–即方法签名:
MimeMessage.setContent(Object theContent,String type);
也可以不用显式的制定消息的内容类型:MimeMessage.setText(String theText);

 

注意:建立地址javax.mail.InternetAddress toAddress=new InternetAddress(String address);

 

 

源码

参考:

http://blog.csdn.net/qq_32371887/article/details/72821291

http://www.cnblogs.com/codeplus/archive/2011/10/30/2229391.html

http://blog.csdn.net/xietansheng/article/details/51673073

http://blog.csdn.net/xietansheng/article/details/51722660

http://www.cnblogs.com/jiaguozhilian/p/5809815.html

http://blog.csdn.net/karem/article/details/4646071

http://blog.csdn.net/csh624366188/article/details/7183457

http://www.cnblogs.com/Ant-soldier/p/6592858.html

http://blog.csdn.net/shuaicihai/article/details/59484175

 

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/146324.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • android app 退出功能,Android 完美退出 App (Exit)

    android app 退出功能,Android 完美退出 App (Exit)最近两天为了解决Android上面退出程序问题折腾了半死,在google&baidu上面找了很久、很久出来的完全千篇一律,说的方法有三,但是经过我试验后全部不行。三个方法分别是:killProcess,这种方式当你kill后Activity会返回到上一个ActivityAndroidLevel8(包含8)前使用一个API来操作,Level8以后又是另外一种,所以不能通用使用…

    2022年7月17日
    21
  • Idea激活码最新教程2021.2.3版本,永久有效激活码,亲测可用,记得收藏

    Idea激活码最新教程2021.2.3版本,永久有效激活码,亲测可用,记得收藏Idea 激活码教程永久有效 2021 2 3 激活码教程 Windows 版永久激活 持续更新 Idea 激活码 2021 2 3 成功激活

    2025年5月22日
    3
  • 分析了10万条B站UP主数据后,我知道了成为百万粉丝UP主的一些秘密「建议收藏」

    分析了10万条B站UP主数据后,我知道了成为百万粉丝UP主的一些秘密「建议收藏」前几天一位好朋友入了B站,问我如何才能成为一名百万粉丝的up主。这不,于是我做了这篇的一些分析,知道了成为百万粉丝up主的一些小秘密。还做了一个昵称生成器,给其昵称起名提供建议。这是她的b站视频截图:关于昵称起名我的想法是这样,是我们把B站这些百万粉丝大佬的昵称分析一下成分构成,根据相关性随机起个名,是不是就有百万粉丝up主昵称的那味了?上面截图是她改名前的昵称,是否会改名,改名后叫什么咱们拭目以待。咱们现在就开始爬取整整:B站up主信息爬取直接通过b站首页去爬是很不方便的,这里我找到了两个第

    2022年6月12日
    49
  • asp.net读取用户控件,自定义加载用户控件

    asp.net读取用户控件,自定义加载用户控件

    2022年3月8日
    46
  • 语义分割最新算法_nonnegative integers

    语义分割最新算法_nonnegative integers翻译来自:https://gist.github.com/khanhnamle1994/e2ff59ddca93c0205ac4e566d40b5e88语义分割方面的资源:https://github.com/mrgloom/awesome-semantic-segmentation1.什么是语义分割语义分割是当今计算机视觉领域的关键问题之一。从宏观上看,语义分割是一项高层次的任务,…

    2022年4月19日
    118
  • CreateFile函数

    CreateFile函数在 include include 的头文件里 HANDLECreate LPCTSTRlpFil 要打开的文件名 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp DWORDdwDesir 文件的操作属性 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp DWORDdwShare 文件共享属性 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp LPSECU

    2025年9月25日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号