引言
使用Apache-Commons-Email发送邮件
环境准备
Maven的pom.xml 文件中引入依赖
1 2 3 4 5
| <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-email</artifactId> <version>1.5</version> </dependency>
|
一个简单的纯文本邮件
HTTP模式下
第一个例子是创建一个简单的email。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| import org.apache.commons.mail.EmailException; import org.apache.commons.mail.SimpleEmail;
public class TestSimpleEmail {
public static void main(String[] args) {
SimpleEmail email = new SimpleEmail(); email.setHostName ("smtp.163.com"); email.setDebug(true); email.setSmtpPort(25); email.setAuthentication ( "from@163.com", "password" ); try { email.addTo ("to@qq.com", "收件人名称"); email.setFrom("from@163.com", "发件人名称", "UTF-8"); email.setSubject ("这是邮件主题内容"); email.setMsg ("这是邮件内容!"); email.send (); System.out.println ("Send email successful!"); } catch (EmailException e) { e.printStackTrace(); } } }
|
如果遇到乱码情况可以通过以下方案解决:
1 2 3 4
| email.setCharset("UTF-8");
email.getMimeMessage().setText("测试邮件内容","UTF-8");
|
开启了HTTPS
需要添加ssl端口,以及开启SSLOnConnect。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| import org.apache.commons.mail.EmailException; import org.apache.commons.mail.SimpleEmail;
public class TestSimpleSSLEmail { public static void main(String[] args) { SimpleEmail email = new SimpleEmail (); email.setHostName ("smtp.qq.com"); email.setSslSmtpPort("465"); email.setAuthentication ("from@qq.com", "password"); email.setSSLOnConnect(true); try { email.addTo ("to@qq.com", "to"); email.setFrom("from@qq.com", "from", "UTF-8"); email.setSubject ("这是邮件主题内容"); email.setMsg ("这是邮件内容!--一个简单的纯文本邮件 --开启了https的情况下 "); email.send (); System.out.println ("Send email successful!"); } catch (EmailException e) { e.printStackTrace(); } } }
|
特别要注意的是qq邮箱进行了加密,所以需要到qq账户设置里面拿到开启stmp发信客户端的密码。
取到一串字符串,然后填写到密码处。不然会报以下的错误。而不是填写QQ账号密码到密码认证处。详细也可以参照QQ客户端说明文档。
发送带附件的邮件
发送带附件的邮件得用MultiPartEmail 类来给邮件添加附件。除过覆盖attach()方法来给邮件添加附件外,这个类就和SimpleEmail类差不多。对于内联或是加入附件的个数是没有限制的。但附件必须是MIME编码。最简单的添加附件的方式是用 EmailAttachment类。
本地附件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| import org.apache.commons.mail.EmailAttachment; import org.apache.commons.mail.EmailException; import org.apache.commons.mail.MultiPartEmail;
public class TestEmailAttachment {
public static void main(String[] args) { EmailAttachment attachment = new EmailAttachment(); attachment.setPath("E:\\qrcode.jpg"); attachment.setDisposition(EmailAttachment.ATTACHMENT); attachment.setDescription("图片"); attachment.setName("qrcode.jpg"); MultiPartEmail email = new MultiPartEmail(); email.setHostName ("smtp.163.com"); email.setSmtpPort(25); email.setAuthentication ("from@163.com","password"); try { email.addTo ("to@qq.com", "收件人名称"); email.setFrom("from@163.com", "发件人名称", "UTF-8"); email.setSubject ("这是邮件主题内容"); email.setMsg ("这是邮件内容!");
email.attach(attachment); email.send(); System.out.println ("Send email successful!"); } catch (EmailException e) { e.printStackTrace(); } } }
|
远程附件
如果没有本地文件,可以用 EmailAttachment 添加任何可用的URL。当邮件发送后,文件会自动加载并加入到邮件内容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| import java.net.MalformedURLException; import java.net.URL; import org.apache.commons.mail.EmailAttachment; import org.apache.commons.mail.EmailException; import org.apache.commons.mail.MultiPartEmail;
public class TestEmailAttachment2 { public static void main(String[] args) throws MalformedURLException { EmailAttachment attachment = new EmailAttachment(); attachment.setURL(new URL("http://www.apache.org/images/asf_logo_wide.gif")); attachment.setDisposition(EmailAttachment.ATTACHMENT); attachment.setDescription("Apache logo"); attachment.setName("asf_logo_wide.gif"); MultiPartEmail email = new MultiPartEmail(); email.setHostName ("smtp.163.com"); email.setSmtpPort(25); email.setAuthentication ("from@163.com","password"); try { email.addTo ("to@qq.com", "收件人名称"); email.setFrom("from@163.com", "发件人名称", "UTF-8"); email.setSubject ("这是邮件主题内容"); email.setMsg ("这是邮件内容!");
email.attach(attachment); email.send(); System.out.println ("Send email successful!"); } catch (EmailException e) { e.printStackTrace(); } } }
|
发送带HTML格式的邮件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| import java.net.MalformedURLException; import java.net.URL; import org.apache.commons.mail.EmailException; import org.apache.commons.mail.HtmlEmail;
public class TestHtmlEmail { public static void main(String[] args) { HtmlEmail email = new HtmlEmail(); email.setHostName ("smtp.163.com"); email.setSmtpPort(25); email.setAuthentication ("from@163.com", "password" ); try { URL url = new URL("http://www.apache.org/images/asf_logo_wide.gif"); String cid = email.embed(url, "Apache logo"); email.addTo ("to@qq.com", "收件人名称"); email.setFrom("from@163.com", "发件人名称", "UTF-8"); email.setSubject ("这是邮件主题内容-发送带HTML格式的邮件"); email.setHtmlMsg("<html>The apache logo - <img src=\"cid:" + cid + "\"></html>"); email.setTextMsg("Your email client does not support HTML messages"); email.send(); System.out.println ("Send email successful!"); } catch (EmailException | MalformedURLException e) { e.printStackTrace(); } } }
|
注意:
- embed()方法返回一个字符串。该字符串是一个随机生成的标识符,必须在图像标记中引用图像的图像。
- 没有调用setmsg()这个例子。因为如果HTML内容里有内联图片的话,这个方法是不能用的。这样我们可以用setHtmlMsg和setTextMsg方法。
发送带嵌入图片的HTML文本
前面说的是创建带嵌入图片的HTML邮件,但是用HTML邮件模板来处理图片是很麻烦的。ImageHtmlEmail类能解决这个问题,它能很方便的将所有外部图片转化为内联图片。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| import java.net.MalformedURLException; import java.net.URL; import org.apache.commons.mail.EmailException; import org.apache.commons.mail.ImageHtmlEmail; import org.apache.commons.mail.resolver.DataSourceUrlResolver;
public class TestHtmlEmail2 { public static void main(String[] args) { ImageHtmlEmail email = new ImageHtmlEmail(); email.setHostName ("smtp.163.com"); email.setSmtpPort(25); email.setAuthentication ( "from@163.com", "password" ); String htmlEmailTemplate = "嵌入图片的HTML文本:<img src=\"http://www.apache.org/images/feather.gif\"> ...."; try { URL url = new URL("http://www.apache.org"); email.setDataSourceResolver(new DataSourceUrlResolver(url)); email.addTo("to@sina.com", "收件人名称"); email.setFrom("from@qq.com", "发件人名称", "UTF-8"); email.setSubject("这是邮件主题内容");
email.setHtmlMsg(htmlEmailTemplate); email.setCharset("UTF-8");
email.setTextMsg("Your email client does not support HTML messages");
email.send(); System.out.println("Send email successful!"); } catch (MalformedURLException | EmailException e) { e.printStackTrace(); } } }
|
调试
JavaMail API支持调试选项,通过调用setDebug(true)来开启调试。调试信息会通过System.out打印出来。
commons-email的安全设置的特性。可以用EmailLiveTest和EmailConfiguration类在真正的SMTP服务器上测试commons-email。
认证
如果要对SMTP服务器进行认证,可以在发邮件前调用setAuthentication(userName,password)方法测试。这将会在JavaMail API发送邮件时创建DefaultAuthenticator实例,要支持此方法得让你的服务器支持RFC255协议。
可以用javax.mail.Authenticator的子类来完成更加复杂的认证,如弹出个对话框等。当想收集并处理用户信息时,必须覆盖getPasswordAuthentication()方法。用Email.setAuthenticator方法可以创建新的Authenticator类。
参考文章
http://commons.apache.org/proper/commons-email/userguide.html
Apache Commons Email 发送邮件的用法介绍以及实战练习