利用JavaMail发送QQ邮件

一、RFC882文档简单说明

  RFC882文档规定了如何编写一封简单的邮件(纯文本邮件),一封简单的邮件包含邮件头和邮件体两个部分,邮件头和邮件体之间使用空行分隔。

  邮件头包含的内容有:

  1. from字段   --用于指明发件人
  2. to字段       --用于指明收件人
  3. subject字段  --用于说明邮件主题
  4. cc字段      -- 抄送,将邮件发送给收件人的同时抄送给另一个收件人,收件人可以看到邮件抄送给了谁
  5. 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='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='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学习总结(五十一)——邮件的发送与接收原理

JavaWeb学习总结(五十二)——使用JavaMail创建邮件和发送邮件

JavaWeb学习总结(五十三)——Web应用中使用JavaMail发送邮件

学习和码字过程难免出现疏漏,欢迎指正!QQ:1801888312
原文地址:https://www.cnblogs.com/liuguo/p/13629831.html