参照地址
1、JavaMail 介绍
- JavaMail 是sun公司(现以被甲骨文收购)为方便Java开发人员在应用程序中实现邮件发送和接收功能而提供的一套标准开发包,它支持一些常用的邮件协议,如前面所讲的SMTP,POP3,IMAP,还有MIME等。我们在使用JavaMail API 编写邮件时,无须考虑邮件的底层实现细节,只要调用JavaMail 开发包中相应的API类就可以了。
- JavaMail 下载地址: https://github.com/javaee/javamail/releases
2、JavaMail API
- JavaMail API 按照功能可以划分为如下三大类:
①、创建和解析邮件的API
②、发送邮件的API
③、接收邮件的API
- 以上三种类型的API在JavaMail 中由多个类组成,但是主要有四个核心类,我们在编写程序时,记住这四个核心类,就很容易编写出Java邮件处理程序。
- Message 类:javax.mail.Message 类是创建和解析邮件的核心 API,这是一个抽象类,通常使用它的子类javax.mail.internet.MimeMessage 类。它的实例对象表示一份电子邮件。客户端程序发送邮件时,首先使用创建邮件的 JavaMail API 创建出封装了邮件数据的 Message 对象,然后把这个对象传递给邮件发送API(Transport 类) 发送。客户端程序接收邮件时,邮件接收API把接收到的邮件数据封装在Message 类的实例中,客户端程序在使用邮件解析API从这个对象中解析收到的邮件数据。
- Transport 类:javax.mail.Transport 类是发送邮件的核心API 类,它的实例对象代表实现了某个邮件发送协议的邮件发送对象,例如 SMTP 协议,客户端程序创建好 Message 对象后,只需要使用邮件发送API 得到 Transport 对象,然后把 Message 对象传递给 Transport 对象,并调用它的发送方法,就可以把邮件发送给指定的 SMTP 服务器。
- Store 类:javax.mail.Store 类是接收邮件的核心 API 类,它的实例对象代表实现了某个邮件接收协议的邮件接收对象,例如 POP3 协议,客户端程序接收邮件时,只需要使用邮件接收 API 得到 Store 对象,然后调用 Store 对象的接收方法,就可以从指定的 POP3 服务器获得邮件数据,并把这些邮件数据封装到表示邮件的 Message 对象中。
- Session 类:javax.mail.Session 类用于定义整个应用程序所需的环境信息,以及收集客户端与邮件服务器建立网络连接的会话信息,例如邮件服务器的主机名、端口号、采用的邮件发送和接收协议等。Session 对象根据这些信息构建用于邮件收发的 Transport 和 Store 对象,以及为客户端创建 Message 对象时提供信息支持。
3、使用 JavaMail 发送简单的纯文本邮件
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Date;
import java.util.Properties;
/**
* 简单的发送邮件
*/
public class JavaEmailDemo {
public static void main(String[] args) throws Exception {
//1. 创建参数配置, 用于连接邮件服务器的参数配置
Properties props = new Properties();
//邮箱协议
props.setProperty("mail.transport.protocol", "smtp");//使用协议:mstp
//邮箱协议地址
//发件人邮箱的 SMTP 服务器地址, 必须准确, 不同邮件服务器地址不同, 一般格式为: smtp.xxx.com
props.setProperty("mail.smtp.host", "smtp.qq.com");//协议地址
//邮箱协议端口号
props.setProperty("mail.smtp.port", "465");//协议端口号
//邮箱是否需要授权
props.setProperty("mail.smpt.auth", "true");//需要授权
//qq:需要 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");
//2. 根据配置创建会话对象, 用于和邮件服务器交互
Session session = Session.getInstance(props);
//开启日志
session.setDebug(true);
//3. 创建邮件
Message message = createMessage(session, "888888@qq.com", "666666@qq.com");
//4. 根据 session 获取传输对象
Transport transport = session.getTransport();
//5. 使用 邮箱账号 和 密码 连接邮件服务器, 这里认证的邮箱必须与 message 中的发件人邮箱一致, 否则报错
/*
* PS_01: 成败的判断关键在此一句, 如果连接服务器失败, 都会在控制台输出相应失败原因的 log,
* ======>仔细查看失败原因, 有些邮箱服务器会返回错误码或查看错误类型的链接, 根据给出的错误
* ======>类型到对应邮件服务器的帮助网站上查看具体失败原因。
* PS_02: 连接失败的原因通常为以下几点, 仔细检查代码:
* ======>(1) 邮箱没有开启 SMTP 服务;
* ======>(2) 邮箱密码错误, 例如某些邮箱开启了独立密码;
* ======>(3) 邮箱服务器要求必须要使用 SSL 安全连接;
* ======>(4) 请求过于频繁或其他原因, 被邮件服务器拒绝服务;
* ======>(5) 如果以上几点都确定无误, 到邮件服务器网站查找帮助。
* PS_03: 仔细看log, 认真看log, 看懂log, 错误原因都在log已说明。
* */
transport.connect("888888@qq.com", "aaaaaaa");//邮箱,授权码
//6. 发送邮件,, 发到所有的收件地址,
// message.getAllRecipients() 获取到的是在创建邮件对象时添加的所有收件人, 抄送人, 密送人
transport.sendMessage(message, message.getAllRecipients());
//7. 关闭连接
transport.close();
System.out.println("发送成功");
}
/**
*
* @param session 和服务器交互的会话
* @param addresser 发件人邮箱
* @param receiver 收件人邮箱
* @return MimeMessage 简单邮件
* @throws Exception
*/
public static Message createMessage(Session session, String addresser, String receiver) throws Exception {
//邮件:标题,正文,收件人,发件人, {附件,图片}
//1. 创建一封邮件
MimeMessage message = new MimeMessage(session);
//2. From: 发件人(昵称有广告嫌疑,避免被邮件服务器误认为是滥发广告以至返回失败,请修改昵称)
/*
* 发件人
* setFrom(Address address)
* InternetAddress(String 发件人, String 发件人的名字, String 字符集)
* */
Address address = new InternetAddress(addresser, "jack", "utf-8");
message.setFrom(addresser);//addFrom 是数组,setFrom 是单个
//3. 收件人
/*
* 收件人
* setRecipients(RecipientType type, Address[] addresses)
* setRecipient(RecipientType type, Address address)
* ==>type:收件人类型;to 普通收件人,cc 抄送,bcc 密送
* ==>address:收件人
* */
message.setRecipient(MimeMessage.RecipientType.BCC, new InternetAddress(receiver, "rose普通收件人", "utf-8"));
//4. 主题
/*
* 主题
* setSubject(String 主题, String 字符集)
* */
message.setSubject("山鬼谣", "utf-8");
//5. 正文 (可以使用html标签)(内容有广告嫌疑,避免被邮件服务器误认为是滥发广告以至返回失败,请修改发送内容)
/*
* 正文
* setContent(Object 正文, String 类型)
* */
message.setContent("你被山西挖矿大学录取了,请于2月30日25时61分61秒,请及时到来.", "text/html;charset=utf-8");
//6. 设置发件时间
/*
* 发送时间
* */
message.setSentDate(new Date());
//7. 保存设置
/*
* 保存邮件
* */
message.saveChanges();
return message;
}
}
4、使用 JavaMail 发送带图片、附件的邮件
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.*;
import java.io.File;
import java.util.Date;
import java.util.Properties;
/**
* 发送邮件附加图片和附件
*/
public class JavaEmailWithAttachmentDemo {
public static void main(String[] args) throws Exception {
//1. 创建参数配置, 用于连接邮件服务器的参数配置
Properties props = new Properties();
//邮箱协议
props.setProperty("mail.transport.protocol", "smtp");//使用协议:mstp
//邮箱协议地址
//发件人邮箱的 SMTP 服务器地址, 必须准确, 不同邮件服务器地址不同, 一般格式为: smtp.xxx.com
props.setProperty("mail.smtp.host", "smtp.qq.com");//协议地址
//邮箱协议端口号
props.setProperty("mail.smtp.port", "465");//协议端口号
//邮箱是否需要授权
props.setProperty("mail.smpt.auth", "true");//需要授权
//qq:需要 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");
//2. 根据配置创建会话对象, 用于和邮件服务器交互
Session session = Session.getInstance(props);
//开启日志
session.setDebug(true);
//3. 创建邮件
Message message = createMessage(session, "8888888@qq.com", "666666@qq.com");
//4. 根据 session 获取传输对象
Transport transport = session.getTransport();
//5. 使用 邮箱账号 和 密码 连接邮件服务器, 这里认证的邮箱必须与 message 中的发件人邮箱一致, 否则报错
transport.connect("8888888@qq.com", "nfkjfpkwtxipecec");//邮箱,授权码
//6. 发送邮件,, 发到所有的收件地址,
// message.getAllRecipients() 获取到的是在创建邮件对象时添加的所有收件人, 抄送人, 密送人
transport.sendMessage(message, message.getAllRecipients());
//7. 关闭连接
transport.close();
System.out.println("发送成功");
}
/**
*
* @param session 和服务器交互的会话
* @param addresser 发件人邮箱
* @param receiver 收件人邮箱
* @return MimeMessage 图片+附件 邮件
* @throws Exception
*/
public static Message createMessage(Session session, String addresser, String receiver) throws Exception {
//邮件:标题,正文,收件人,发件人, {附件,图片}
MimeMessage message = new MimeMessage(session);
/*
* 发件人
* setFrom(Address address)
* InternetAddress(String 发件人, String 发件人的名字, String 字符集)
* */
Address address = new InternetAddress(addresser, "jack", "utf-8");
message.setFrom(addresser);//addFrom 是数组,setFrom 是单个
/*
* 收件人
* setRecipients(RecipientType type, Address[] addresses)
* setRecipient(RecipientType type, Address address)
* ==>type:收件人类型;to 普通收件人,cc 抄送,bcc 密送
* ==>address:收件人
* */
message.setRecipient(MimeMessage.RecipientType.BCC, new InternetAddress(receiver, "rose普通收件人", "utf-8"));
/*
* 主题
* setSubject(String 主题, String 字符集)
* */
message.setSubject("山鬼谣", "utf-8");
//************************************图片
/*
* 图片->文本节点->复合节点->根据要求,变成普通节点
* */
//1. 创建图片节点
MimeBodyPart imageParat = new MimeBodyPart();
//放图片
DataSource dataSource = new FileDataSource("JavaEmail/src/image/美女.jpg");//图片地址
/*
* 这里使用的 idea开发工具路径写 image/美女.jpg 提示找不到路径,
* 所以就试了从项目根目录写测试成功
* */
DataHandler imageDataHandler = new DataHandler(dataSource);// 将图片数据添加到“节点”
imageParat.setDataHandler(imageDataHandler);
//为“图片节点”设置一个唯一编号(在文本“节点”将引用该ID)
imageParat.setContentID("A");
//2. 创建文本节点;目的:为了加载图片节点
MimeBodyPart textPart = new MimeBodyPart();
textPart.setContent("正文内容 image:<img src='cid:A'/>", "text/html;charset=utf-8");
//3. 将图片节点和文本节点组装===>组装成一个 复合节点
MimeMultipart mmTextImage = new MimeMultipart();
mmTextImage.addBodyPart(imageParat);
mmTextImage.addBodyPart(textPart);
//设置关联关系
mmTextImage.setSubType("related");//关联关系
//4. 注意:正文中只能出现 MimeBodyPart 普通节点,不能出现复合节点 MimeMultipart
//MimeMultipart --> MimeBodyPart
MimeBodyPart textImageBodyPart = new MimeBodyPart();
textImageBodyPart.setContent(mmTextImage);
//**********************************************附件
//5. 创建附件节点
MimeBodyPart attachment = new MimeBodyPart();
//附加节点添加 图片
DataHandler fileDataHandler = new DataHandler(new FileDataSource("JavaEmail/src/image/变态.mp4"));
attachment.setDataHandler(fileDataHandler);
//给附件设置文件名 文件名可能乱码使用工具类
attachment.setFileName(MimeUtility.encodeText(fileDataHandler.getName()));
//6. 将刚才处理好的 "文本+图片"(单)节点 与 附件节点 设置成一个新的复合节点
MimeMultipart mm = new MimeMultipart();
mm.addBodyPart(textImageBodyPart);
mm.addBodyPart(attachment);
mm.setSubType("mixed");//混合关系
//###########################
/*
* 设置整个邮件的关系(将最终的混合“节点”作为邮件的内容添加到邮件对象)
* setContent(Object 复合节点, String 类型)
* 正文内容放在了文本节点中了
* */
message.setContent(mm, "text/html;charset=utf-8");
/*
* 设置发送时间
* */
message.setSentDate(new Date());
/*
* 保存邮件
* */
message.saveChanges();
return message;
}
}