使用 Apache Commons Email发送邮件就是这么简单的不能再简单了

在这里插入图片描述

一、快速入门

1.1 介绍

  在线发送、接收邮件,目前是企业应用系统开发中的通用功能需求,例如,在线投递通知、激活账户、发送和用户注册相关的信息等。Apache Commons Email 是 Apache 提供的一个开源的API,是基于 JavaMail API 而构建的一套用 Java 操作邮件系统的工具类库。其提供了常用的邮件发送和接收类,对 JavaMail API进行了封装,从而简化其操作,使用起来非常方便。
  我们可以在官网网站 http://commons.apache.org/email 中下载与邮件系统有关的 Commons Email 组件的系统库文件 commons-email。Commons Email 组件依赖于标准的 JavaMail API 类库,还需要下载与 JavaMail API 有关的系统库文件。相关依赖如下所示:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-email</artifactId>
    <version>1.5</version>
</dependency>

<dependency>
	   <groupId>com.sun.mail</groupId>
	   <artifactId>javax.mail</artifactId>
	   <version>1.5.6</version>
</dependency>

1.2 关键对象

  Apache commons email l的核心是Email类,它是一个抽象类,提供了发送邮件的核心功能。具体有以下几个实现类:

实现类说明
SimpleEmail发送简单邮件,即纯文本邮件
MultiPartEmail发送带附件的邮件
HtmlEmail发送超文本邮件
ImageHtmlEmail发送图文混排的超文本邮件
EmailAttachment

下面是Email的类图

请添加图片描述

通过类图可以看到很多额外信息:

  • HtmlEmail 继承了 MultiPartEmail,说明它也同时支持附件。
  • ImageHtmlEmail 继承了 HtmlEmail,说明它也同时支持附件和超文本。

二、常用功能类的应用

2.1 Email

抽象类 Email 及其主要功能方法说明,如下表所示:

方法说明
addBcc(String email)
addCc(String email)
addReplyTo(String email)
addTo(String email)设置收件人邮箱
isSendPartial()
isSSLOnConnect()
send()发送邮件
sendMimeMessage()
setAuthentication(String userName,String password)SMTP服务器进行身份验证,用户名和密码为邮箱的账号和授权码
setBounceAddress(String email)
setCharset(String charset)设置邮件的字符集编码
setContent(MimeMultipart mimeMultipart)
setContent(Object obj, String contentType)
setDebug(boolean d)是否激活任何邮件类的调试
setFrom(String email)设置发件人邮箱
setHostName(String hostName)设置使用发电子邮件的邮件服务器
setMsg(String msg)设置邮件正文内容。
该方法为抽象方法,需要在子类中被重写
setSendPartial(boolean sendPartial)
setSentDate(Date date)
setSmtpPort(int portNumber)邮件服务器smtp协议的SSL端口
setSocketTimeout(int socketTimeout)
setSSLOnConnect(boolean ssl)设置SSL安全连接
setSubject(String subject)设置邮件主题

2.2 SimpleEmail

  利用该类可以实现发送简单的文本类型的邮件,并利用 SimpleEmail 类中的设置邮件内容的方法 setMsg 定义邮件正文内容。注意: SimpleEmail 只能发送文本类型的邮件,并且不能带附件。

方法说明

2.3 MultiPartEmail

  EmailAttachment 类知识包装邮件的附件,如果真正要实现发送带附件文件的邮件,此时应该选择 MultiPartEmail 类作为对邮件内容的包装,因为 MultiPartEmail 类提供了有将附件文件添加到邮件体中的各个功能方法。下面为 MultiPartEmail 类中的主要功能方法的定义,如下表所示:

方法说明
addPart(MimeMultipart multipart)
addPart(MimeMultipart multipart, int index)
addPart(String partContent, String partContentType)
MultiPartEmail attach(DataSource ds,String name,String description)
attach(DataSource ds,String name,String description,String disposition)
attach(EmailAttachment attachment)
attach(File file)
attach(URL url, String name, String description)
attach(URL url,String name,String description,String disposition)

2.4 HtmlEmail

  HtmlEmail 类为开发人员提供发送 HTML 格式的邮件内容,利用 HtmlEmail 类中的 setHtmlMsg 方法可以设置 HTML 格式的邮件正文内容,而利用 setTextMsg 方法可以设置文本格式的邮件正文内容,可以根据邮件正文内容格式的具体需要进行选择。

方法说明

2.5 ImageHtmlEmail

ImageHtmlEmail类通常是用来发送Html格式并内嵌图片的邮件,拥有所有HtmlEmail的功能,但是图片主要是以html内嵌的为主

2.6 EmailAttachment

利用该类可以实现发送带附件的邮件,并利用它实现对邮件的附件文件进行包装,主要有下面几种常用的方法:

方法说明
setDescription(String desc)设置附件描述,能够随便写
setDisposition(String disposition)表示点击附件是否需要直接打开或者以附件形式下载
setName(String name)附件名,注意和文件格式一致,这将是接收人下载下来的文件名称。
如果附件是中文名会在乱码,通过 MimeUtility.encodeText 转码
setPath(String path)指定附件在本地的绝对路径
setURL(URL url)设置网络附件的URL

三、使用介绍

3.1 邮箱设置

  想要通过程序发送邮件,首先需要有一个邮箱做为发件人,并开启POP3/SMTP服务,获取对应邮箱的授权码,不同的邮箱开启方式和位置不甚相同,以下以163邮箱和QQ邮箱为例说明,其余邮箱可以自行搜索开启方式。

  • 163邮箱

  进入邮箱首页,点击设置,选择下拉选项的“POP3/SMTP/IMAP”,点击进入 POP3/SMTP/IMAP 部分 ,点击“POP3/SMTP服务”后的【开启】,弹出页面,用绑定手机扫码发送短信,发送完毕后可获得授权码。

请添加图片描述

  • QQ邮箱

  进入邮箱首页,点击设置,切换到账户页签,将页面滑动到“POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务 ”部分,点击“POP3/SMTP服务”后的【开启】,会弹出页面提醒用QQ绑定的手机号发送短信,发送完毕后,点击“我已发送”,即可获得授权码。

在这里插入图片描述

3.2 简单邮件

简单邮件就是纯文本邮件,格式简单,下面看看使用Commons-Email的API的例子,示例代码如下所示:

/**
 * 发送内容为简单文本的邮件
 */
public static void sendSimpleTextEmail() throws EmailException {
    Email email = new SimpleEmail();
    email.setHostName(MAIL_SERVER_HOST);
    email.setSmtpPort(25);
    email.setAuthenticator(new DefaultAuthenticator(MAIL_SERVER_USER, MAIL_SERVER_PASSWORD));
    email.setSSLOnConnect(true);
    email.setDebug(DEBUG_MODE);
    email.setCharset("UTF-8");
    email.setFrom(MAIL_SERVER_USER, NICK_NAME);
    email.addTo("duleilewuhen@sina.com");
    email.setSubject("测试邮件");
    email.setMsg("这是一封简单的邮件This is the third test mail ... :-)");
    email.send();
}

注意:Email 实例对象的 setHostName 的显示调用设置将用于发送邮件的传出SMTP服务器的地址,如果没有设置,将从系统属性 mail.host 中获得。

3.3 带附件的电子邮件

发送包含附件的邮件,这里用到了一个 EmailAttachment 对象,也就是附件的意思

/**
 * 发送包含附件的邮件(附件为本地资源)
 */
public static void sendEmailsWithAttachment() throws EmailException, UnsupportedEncodingException {
    // 建立一个attachment(附件)对象
    EmailAttachment attachment = new EmailAttachment();
    attachment.setPath("/Users/dllwh/Desktop/redis.sh");
    attachment.setDisposition(EmailAttachment.ATTACHMENT);
    attachment.setDescription("Picture");
    attachment.setName(MimeUtility.encodeText(" 测试 "));

    // 由于要上传附件,因此用MultiPartEmail()方法建立一个email对象
    MultiPartEmail email = new MultiPartEmail();
    email.setHostName(MAIL_SERVER_HOST);
    email.setAuthentication(MAIL_SERVER_USER, MAIL_SERVER_PASSWORD);
    email.setFrom(MAIL_SERVER_USER, NICK_NAME);
    email.addTo("duleilewuhen@sina.com");
    email.setSubject("测试邮件");
    email.setMsg("测试邮件的正文内容!");
    email.setCharset("UTF-8");
    // 将附件添加到邮件
    email.attach(attachment);
    email.send();
}

发送包含附近的邮件(附件为在线资源),这个与上传本地附件稍有区别,注意一下就行

/**
 * 发送包含附件的邮件(附件为在线资源,在发送时自动将网络上资源下载发送)
 */
public static void sendEmailsWithOnlineAttachment() throws MalformedURLException, EmailException {
    EmailAttachment attachment = new EmailAttachment();
    // 设置在线资源路径,和上传本地附件的惟一区别
    attachment.setURL(new URL("https://www.apache.org/images/asf_logo_wide.gif"));
    attachment.setDisposition(EmailAttachment.ATTACHMENT);
    attachment.setDescription("Apache logo");
    attachment.setName("Apache logo.gif");

    MultiPartEmail email = new MultiPartEmail();
    email.setHostName(MAIL_SERVER_HOST);
    email.setAuthentication(MAIL_SERVER_USER, MAIL_SERVER_PASSWORD);
    email.setFrom(MAIL_SERVER_USER, NICK_NAME);
    email.addTo("duleilewuhen@sina.com");
    email.setSubject("测试邮件");
    email.setMsg("发送的图片是一个网站的logo");
    email.attach(attachment);

    email.send();
}

3.4 HTML格式的邮件

  发送内容为HTML格式的邮件,有些邮件直接打开就是一个HTML页面。虽然不必定用到,能够了解一下。发送HTML格式的电子邮件是通过使用 HtmlEmail 类来完成的,该类的工作方式与 MultiPartEmail 类完全相同,其中包括用于设置html内容的方法,如果收件人不支持HTML电子邮件,则添加替代文本内容,并添加内嵌图像。

/**
 * 发送内容为HTML格式的邮件,内嵌图片
 */
public static void sendHtmlMailWithImage() throws EmailException, MalformedURLException {
    HtmlEmail email = new HtmlEmail();
    email.setHostName(MAIL_SERVER_HOST);
    email.addTo("duleilewuhen@sina.com");
    email.setFrom(MAIL_SERVER_USER, NICK_NAME);
    email.setSubject("Test email with inline image");
    email.setAuthenticator(new DefaultAuthenticator(MAIL_SERVER_USER, MAIL_SERVER_PASSWORD));
    email.setCharset("UTF-8");

    // 图片的网络地址
    URL url = new URL("https://www.apache.org/images/asf_logo_wide.gif");
    // 该字符串是随机生成的标识符,必须用于引用图像标签中的图像。
    String cid = email.embed(url, "Apache logo");

    // 将图片引入html标签
    email.setHtmlMsg("<html>The apache logo - <img src=\"cid:" + cid + "\"></html>");

    // 额外提示
    email.setTextMsg("您的邮件不支持html格式");

    email.send();
}

  从上面示例中,可以看出HtmlEmail其实也可以发送图片,那ImageHtmlEmail存在的意义是什么呢?其实HtmlEmail发送图片都需要调用其embed方法,并将其返回值设置到 <img> 标签的src上,示例如下:

// embed方法有多个重载方法,支持URL,本地文件等
String cid = email.embed(new File("D:\\commons mail\\images\\5.jpg"));
email.setHtmlMsg("<html><img src=\"cid:" + cid + "\"></html>");

  如果在我们的电子邮箱中,使用的内嵌图数量很少时,可以使用上面的方式。但是如果是大量的内嵌在线图片时,我们可以通过使用 ImageHtmlEmail 来解决每次输入全路径的URL问题。

/**
 * 发送内容为HTML格式的邮件,内嵌图片
 */
public void sendHtmlMailWithImageByDataSource() throws MalformedURLException, EmailException {
    ImageHtmlEmail email = new ImageHtmlEmail();
    email.setHostName(MAIL_SERVER_HOST);
    email.setSmtpPort(456);
    email.setSSLOnConnect(true);
    email.setAuthentication(MAIL_SERVER_USER, MAIL_SERVER_PASSWORD);
    email.setFrom(MAIL_SERVER_USER, NICK_NAME);
    email.addTo("duleilewuhen@sina.com");
    email.setCharset("UTF-8");
    email.setSubject("测试邮件");
    URL url = new URL("https://www.baidu.com");
    // 这样HTML内容里如果有此路径下的图片会直接内联
    email.setDataSourceResolver(new DataSourceUrlResolver(url));
    String htmlEmail = "这里<img src='https://www.baidu.com/img/bd_logo1.png'>有图片。";
    email.setHtmlMsg(htmlEmail);
    // 额外提示
    email.setTextMsg("你的邮件客户端不支持html邮件");
    email.send();
}

说明:我们创建一个引用一些图像的HTML电子邮件模板,所有引用的图像都通过指定的DataSourceResolver自动转换为内嵌图像。这里用到了DataSourceFileResolver对象,和DataSourceUrlResolver对象,前者能够解析本地文件路径,后者能够解析网络路径。

四、注意事项

4.1 公网邮箱安全参数

  我们在客户端设置邮箱或者 JavaMail 编程的时候,我们都会去查找这些公网邮箱的 IMAP/SMTP/POP3 地址,这里总结了主流的邮件服务商关于IMAP/SMTP/POP3 地址和端口的参数设置。

  • Gmail

    服务器名称服务器地址SSL协议端口非SSL协议端口
    IMAPimap.gmail.com993/
    SMTPsmtp.gmail.com465/
    POP3pop.gmail.com995/
  • QQ邮箱

    服务器名称服务器地址SSL协议端口非SSL协议端口
    IMAPimap.qq.com993143
    SMTPsmtp.qq.com465或58725
    POP3pop.qq.com995110
  • 163邮箱

    服务器名称服务器地址SSL协议端口非SSL协议端口
    IMAPimap.163.com993143
    SMTPsmtp.163.com465或99425
    POP3pop.163.com995110
  • 阿里云邮箱

    服务器名称服务器地址SSL协议端口非SSL协议端口
    IMAPimap.aliyun.com993143
    SMTPsmtp.aliyun.com46525
    POP3pop.aliyun.com995110
  • 微软outlook邮箱

    服务器名称服务器地址SSL协议端口非SSL协议端口
    IMAPpod51003.outlook.com993/
    SMTPpod51003.outlook.com/587
    POP3pod51003.outlook.com995/

4.2 邮箱授权码介绍

  一些邮箱的服务商为了用户的使用安全推出了授权码,用于做为登录第三方客户端的专用密码。一般在邮箱账号的设置项中有开POP3、IMAP、SMTP、Exchange等服务,然后通过平台验证就会获取该邮箱账号的授权码。这里以QQ邮箱获取授权码为例子介绍下,这里以开启IMAP/SMTP服务为例子:

请添加图片描述

通过QQ的密密保验证后,我们可以看到下方的授权码

请添加图片描述

然后在我们的程序中将该授权码当做密码使用即可。

五、总结

Commons Email 做为Java发送电子邮件的工具类,API简单易懂,大大简化了Java邮件发送程序的复杂度,用来代替Java自带的API是不错的选择。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

独泪了无痕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值