利用JavaMail发送QQ邮件
一、RFC882文档简单说明
RFC882文档规定了如何编写一封简单的邮件(纯文本邮件),一封简单的邮件包含邮件头和邮件体两个部分,邮件头和邮件体之间使用空行分隔。
邮件头包含的内容有:
- from字段 --用于指明发件人
- to字段 --用于指明收件人
- subject字段 --用于说明邮件主题
- cc字段 -- 抄送,将邮件发送给收件人的同时抄送给另一个收件人,收件人可以看到邮件抄送给了谁
- bcc字段 -- 密送,将邮件发送给收件人的同时将邮件秘密发送给另一个收件人,收件人无法看到邮件密送给了谁
邮件体指的就是邮件的具体内容。
二、MIME协议简单介绍
在我们的实际开发当中,一封邮件既可能包含图片,又可能包含有附件,在这样的情况下,RFC882文档规定的邮件格式就无法满足要求了。
MIME协议是对RFC822文档的升级和补充,它描述了如何生产一封复杂的邮件。通常我们把MIME协议描述的邮件称之为MIME邮件。MIME协议描述的数据称之为MIME消息。
对于一封复杂邮件,如果包含了多个不同的数据,MIME协议规定了要使用分隔线对多段数据进行分隔,并使用Content-Type头字段对数据的类型、以及多个数据之间的关系进行描述。
三、使用JavaMail创建邮件和发送邮件
JavaMail创建的邮件是基于MIME协议的。因此可以使用JavaMail创建出包含图片,包含附件的复杂邮件。
3.1、JavaMail API的简单介绍
四、开发前的准备
4.1、确保QQ邮箱已经授权
去到QQ邮箱首页——>设置——>账户,滚动条拉到最下边,确保红框内开启授权。
4.2、选择合适的Jar包
在Java SE环境下开发,使用最新版的JavaMail.jar(目前最新的是1.6.2版本)会报错,错误原因和解决办法网上也都有。但为了不那么麻烦,大家可以用版本较旧一点的Jar包,这样就不会报错了(本测试程序使用的Jar,https://mvnrepository.com/artifact/javax.mail/mail/1.4.7)。
4.3、发送简单的邮件(纯文本)
import java.util.Date; import java.util.Properties; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; /** * 只发送简单的文本 * @author Snail * */ public class SimpleEmail { public static void main(String[] args) throws Exception { Session session = Session.getInstance(getConfig()); // 开启日志提示 session.setDebug(true); MimeMessage mm = createMail(session, "1801888312@qq.com", "202132061@qq.com"); // 建立链接对象 Transport ts = session.getTransport(); ts.connect("你的QQ邮箱号码", "前边获取的授权码"); // 发送邮件 ts.sendMessage(mm, mm.getAllRecipients()); // 关闭链接 ts.close(); } private static Properties getConfig() { Properties props = new Properties(); // 使用的协议 props.setProperty("mail.transport.protocol", "smtp"); // 邮箱的 SMTP 服务器地址(百度搜:qq邮箱的POP服务器地址是什么) props.setProperty("mail.smtp.host", "smtp.qq.com"); // 邮箱的服务器端口 props.setProperty("mail.smtp.port", "465"); // 是否需要验证用户名密码 props.setProperty("mail.smtp.auth", "true"); // QQ邮箱的话需要进行SSL认证(javax.net.ssl.SSLSocketFactory这个类是jdk自带的支持ssl认证) props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); // 没经过SSL认证的请求,不予处理 props.setProperty("mail.smtp.socketFactory.fallback", "false"); // SSL认证的端口号(一般和邮箱服务器端口号一致) props.setProperty("mail.smtp.socketFactory.port", "465"); return props; } private static MimeMessage createMail(Session session, String from, String to) throws Exception { // 邮件:收件人,发件人,标题,内容(附件,图片) MimeMessage mm = new MimeMessage(session); // 发件人地址,发件人名字,字符编码 mm.setFrom(new InternetAddress(from, "发件人名字", "UTF-8")); // 设置收件人,TO:普通收件人 CC:抄送 BCC:密送 // cc字段 -- 抄送,将邮件发送给收件人的同时抄送给另一个收件人,收件人可以看到邮件抄送给了谁 // bcc字段 -- 密送,将邮件发送给收件人的同时将邮件秘密发送给另一个收件人,收件人无法看到邮件密送给了谁 mm.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(to, "普通收件人", "UTF-8")); // 设置发送日期 mm.setSentDate(new Date()); // 设置标题 mm.setSubject("这是标题", "UTF-8"); // 正文内容 mm.setContent("<h2>邮件的内容哦!可以写HTML代码的呢!</h2>", "text/html;charset=UTF-8"); // 保存邮件 mm.saveChanges(); return mm; } }
4.4、发送带图片的邮件
Main方法和getConfig方法和前边的一样,只是createMail方法稍微有些改动,下面只贴出createMail方法中的代码。注:dog.jpg是项目src目录下存放的一张图片。
private static MimeMessage createMail(Session session, String from, String to) throws Exception { // 邮件:收件人,发件人,标题,内容(附件,图片) MimeMessage mm = new MimeMessage(session); // 发件人地址,发件人名字,字符编码 mm.setFrom(new InternetAddress(from, "发件人名字", "UTF-8")); // 设置收件人,TO:普通收件人 CC:抄送 BCC:密送 mm.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(to, "普通收件人", "UTF-8")); // 设置发送日期 mm.setSentDate(new Date()); // 设置标题 mm.setSubject("我爱中国", "UTF-8"); // 设置文字内容 MimeBodyPart text = new MimeBodyPart(); text.setContent("<h2>图片可爱吗?</h2><img src='cid:picture.jpg' style='width:100px;'/>", "text/html;charset=utf-8"); // 设置图片 // 挖个坑 MimeBodyPart image = new MimeBodyPart(); // 拿来萝卜 DataHandler dh=new DataHandler(new FileDataSource("src/dog.jpg")); // 把萝卜种进去 image.setDataHandler(dh); // 给萝卜起个名字,供前边的cid使用 image.setContentID("picture"); // 再声明一个容器 MimeMultipart mp=new MimeMultipart(); // 把文字内容放进去 mp.addBodyPart(text); // 把图片内容放进去 mp.addBodyPart(image); // 声明两者的关系 mp.setSubType("related"); // 把MimeMultipart放入到MimeMessage中 mm.setContent(mp); // 保存邮件 mm.saveChanges(); return mm; }
4.5、发送带附件的邮件
private static MimeMessage createMail(Session session, String from, String to) throws Exception { // 邮件:收件人,发件人,标题,内容(附件,图片) MimeMessage mm = new MimeMessage(session); // 发件人地址,发件人名字,字符编码 mm.setFrom(new InternetAddress(from, "发件人名字", "UTF-8")); // 设置收件人,TO:普通收件人 CC:抄送 BCC:密送 mm.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(to, "普通收件人", "UTF-8")); // 设置发送日期 mm.setSentDate(new Date()); // 设置标题 mm.setSubject("我爱中国", "UTF-8"); // 设置文字内容 MimeBodyPart text = new MimeBodyPart(); text.setContent("<h2>这次给你发一个附件</h2>", "text/html;charset=utf-8"); // 设置附件 // 挖个坑 MimeBodyPart file = new MimeBodyPart(); // 拿来萝卜 DataHandler dh = new DataHandler(new FileDataSource("src/dog.jpg")); // 把萝卜种进去 file.setDataHandler(dh); // 给萝卜起个名字 file.setFileName(dh.getName()); // 再声明一个容器 MimeMultipart mp = new MimeMultipart(); // 把文字内容放进去 mp.addBodyPart(text); // 把附件放进去 mp.addBodyPart(file); // 声明两者的关系 mp.setSubType("mixed"); // 把MimeMultipart放入到MimeMessage中 mm.setContent(mp); // 保存邮件 mm.saveChanges(); return mm; }
可以看出,与发送图片只是稍微有点不同,主要不同点为 mp.setSubType()中的参数和图片的cid以及附件的filename。
4.6、发送带图片和附件的邮件
private static MimeMessage createMail(Session session, String from, String to) throws Exception { // 邮件:收件人,发件人,标题,内容(附件,图片) MimeMessage mm = new MimeMessage(session); // 发件人地址,发件人名字,字符编码 mm.setFrom(new InternetAddress(from, "发件人名字", "UTF-8")); // 设置收件人,TO:普通收件人 CC:抄送 BCC:密送 mm.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(to, "普通收件人", "UTF-8")); // 设置发送日期 mm.setSentDate(new Date()); // 设置标题 mm.setSubject("正文,图片,附件", "UTF-8"); // 设置文字内容 MimeBodyPart text = new MimeBodyPart(); text.setContent("<h2>这次既有附件,又有图片</h2><img src='cid:dog.jpg' style='width:100px;'/>", "text/html;charset=utf-8"); // 挖个坑 MimeBodyPart image = new MimeBodyPart(); // 拿来萝卜 DataHandler dh = new DataHandler(new FileDataSource("src/dog.jpg")); // 把萝卜种进去 image.setDataHandler(dh); // 给萝卜起个名字,供前边的cid使用 image.setContentID("dog"); // 设置附件 MimeBodyPart file = new MimeBodyPart(); dh = new DataHandler(new FileDataSource("src/dog.jpg")); file.setDataHandler(dh); file.setFileName(dh.getName()); // 再声明一个容器 MimeMultipart mp = new MimeMultipart(); // 把文字内容放进去 mp.addBodyPart(text); // 把图片放进去 mp.addBodyPart(image); // 声明两者的关系 mp.setSubType("related"); MimeBodyPart text_image = new MimeBodyPart(); text_image.setContent(mp); MimeMultipart mp1 = new MimeMultipart(); mp1.addBodyPart(text_image); mp1.addBodyPart(file); mp1.setSubType("mixed"); // 把MimeMultipart放入到MimeMessage中 mm.setContent(mp1); // 保存邮件 mm.saveChanges(); return mm; }
五、致谢
本文只是简单的讲了下一些理论和实战知识,如果想更加深入地了解相关知识的话,下面一些链接或许会帮助到你。本文也对于下边的文章有所参考,巧合的是,这些文章的作者都是同一个人,非常感谢这些文章的作者——孤傲苍狼!该博主的其他文章质量也特别高,推荐大家去看看哦!。
JavaWeb学习总结(五十二)——使用JavaMail创建邮件和发送邮件
JavaWeb学习总结(五十三)——Web应用中使用JavaMail发送邮件