JavaMail
使用Maven进行导包
基础包:
<!-- JavaMail基本包 --> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.5.0-b01</version> </dependency>
框架包:
<!-- 邮件发送的扩展包 --> <dependency> <groupId>javax.activation</groupId> <artifactId>activation</artifactId> <version>1.1</version> </dependency>
此框架增加了对任何数据块的分类、以及对它们的处理的特性
注意:activation扩展包在Java6之后已经合并到了JDK中,而JDK5之前需要另外下载扩展包
Properties属性认证
两种使用方式,一种是直接在对象里面使用(不推荐),还有是定义一个配置文件(Mail.properties
)把属性存放到文件里面(推荐)
属性名 | 属性类别 | 说明 |
---|---|---|
mail.smtp.host | String | SMTP服务器地址 |
mail.smtp.port | int | SMTP服务器端口号,默认25 |
mail.smtp.auth | boolean | SMTP服务器是否需要用户认证,默认false |
mail.smtp.user | String | SMTP默认登陆用户名 |
mail.smtp.from | String | 默认的邮件发送源地址 |
mail.smtp.socketFactory.class | String | socket工厂类,通过设置该属性可以覆盖提供者默认的实现,必须实现javax.NET.SocketFactory接口 |
mail.smtp.socketFactory.port | int | 指定socket工程类所用的端口号,默认使用默认的端口号 |
mail.smtp.socketFactory.fallback | boolean | 设置为true时,当使用指定的socket类创建socket失败后,将使用Java.net.Socket创建socket,默认为true |
mail.smtp.timeout | int | 连接超时时间,单位为毫秒,默认永不超时 |
Session 会话对象
创建
Session
对象时没有物理连接,只是一堆配置信息的集合
获取内容:new Session.getDefaultInstance()
传值(Properties pr,Authenticator au) | 说明 |
---|---|
getDefaultInstance(pr) | 返回一个默认的邮件会话实例;使用默认的认证器。 |
getDefaultInstance(pr,au) | 返回一个默认的邮件会话实例;使用指定的认证器。 |
getInstance(pr) | 它也返回一个新的邮件会话实例;使用默认的属性和认证器。 |
getInstance(pr,au) | 它也返回一个新的邮件会话实例;使用指定的属性和认证器。 |
使用Session
对象时要获取相对应的(host、port、auth)三个属性,把这三个属性按照属性认证的格式放入Mail
配置文件中(以下为QQ邮箱)
mail.smtp.host=smtp.qq.com
mail.smtp.port=587
mail.smtp.auth=true
然后通过代码获取
public class MailUtils {
// 邮箱连接
private static Session session;
// 认证器
private static MyAuthenticator myAuthenticator;
// 初始化邮箱连接
static {
try {
Properties properties = new Properties();
properties.load(MailUtils.class.getResourceAsStream("/Mail.properties"));
myAuthenticator = new MyAuthenticator();
session = Session.getDefaultInstance(properties, myAuthenticator);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
// 返回会话
public static Session getSession() {
return session;
}
// 返回当前使用账户
public static String getUserName() {
return MyAuthenticator.getUserName();
}
}
Message 消息对象
获取到了
Session
对象就可以进行邮件的收取与发送,期中的发送功能就是用Message
类来完成,因为这是一个抽象类,所以一般用MimeMessage
类
实例化:new MimeMessage(Session)
发件人、收件人、主题
方法 | 说明 |
---|---|
setFrom(InternetAddress) | 设置邮件的发件人地址 |
addRecipient(Message.RecipientType.type, Address) | 添加邮件的收件人地址,其中 type 可以是 TO(直接发送)、CC(抄送)或 BCC(密送) |
addRecipients(Message.RecipientType.type, Address[]) | 跟上面的一样,只不过收件人可以是多个 |
setSubject(String) | 邮件的主题 |
邮件内容
方法 | 说明 |
---|---|
setText(String) | 邮件的内容 |
setContent(Multipart) | 设置复杂邮件的内容, Multipart是一个包含多个 BodyPart 的对象 |
addAttachment(String, DataSource) | 添加邮件的附件,其中 String是附件的文件名,DataSource 是表示附件数据的对象 |
setSentDate(Date) | 设置邮件的发送日期 |
getContent() | 获取邮件的内容,返回一个 Object 对象,需要根据邮件的类型进行类型转换 |
发送两种邮件
纯邮件
Message message = new MimeMessage(MailUtils.getSession());
message.setSubject("我是主题");
message.setText("我是内容");
message.setFrom(new InternetAddress(MailUtils.getUserName()));
message.setRecipient(Message.RecipientType.TO, new InternetAddress("收件人"));
Transport.send(message);
HTML邮件
这种邮件比较特殊,可以使用
html
的方式进行发送邮件,这会使邮件变得更精美需要有两种对象:
Multipart
、BodyPart
BodyPart
方法 | 说明 |
---|---|
setContent(Object obj, String type) | 设置 BodyPart 的内容和内容类型 |
setContentID(String cid) | 设置 BodyPart 的内容ID |
setDescription(String description) | 设置 BodyPart 的描述 |
setFileName(String filename) | 设置 BodyPart 的文件名(用于附件) |
getContentType() | 获取 BodyPart 的内容类型 |
getContentID() | 获取 BodyPart 的内容ID |
getDescription() | 获取 BodyPart 的描述 |
getFileName() | 获取 BodyPart 的文件名 |
getBodyPart() | 获取邮件内容的各个部分 |
Multipart
方法 | 说明 |
---|---|
addBodyPart(BodyPart part) | 向 Multipart 中添加一个 BodyPart |
removeBodyPart(BodyPart part) | 从 Multipart 中移除指定的 BodyPart |
getBodyPart(int index) | 获取指定索引位置的 BodyPart |
getCount() | 获取 Multipart 中包含的 BodyPart 的数量 |
代码
Message message = new MimeMessage(MailUtils.getSession());
message.setFrom(new InternetAddress(MailUtils.getUserName()));
BodyPart bodyPart = new MimeBodyPart();
String html = "<a href='https://www.ximuliunian.top'>测试一下</a>";
bodyPart.setContent(html, "text/html;charset=utf-8");
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(bodyPart);
message.setContent(multipart);
message.addRecipient(Message.RecipientType.TO, new InternetAddress("收件人"));
Transport.send(message);
添加附件
BodyPart bodyPart = new MimeBodyPart();
bodyPart.setFileName("文件名");
bodyPart.setDataHandler(new DataHandler(new FileDataSource(new File("文件路径"))));
在添加文件名的时候使用中文可能会出现乱码情况,这是因为跟服务器编码不统一所导致的,只需要在里面再套一层即可
bodyPart.setFileName(MimeUtility.encodeText("文件名"))
Address 地址
有了
Session
和Message
两个对象后,可以使用AddRess
来确定双方的地址,这也是一个抽象类,一般使用InternetAddress
类
new InternetAddress("邮件地址")
Transport 发送
邮件有发送和接收两种操作,
Transport
进行邮件发送,Store
进行邮件的接收
方法 | 作用 |
---|---|
send() | 发送邮件(静态) |
Store&Folder 收取&内容
读取完邮件后关闭Store&Folder
Store
从session
会话使用getStore("pop3 | imap")
方法获取并连接到Store(邮件服务器)
// MailUtils 为编写的工具类
Store store = MailUtils.getSession().getStore("pop3 | imap");
// 建立连接
store.connect(host,port,user,password);
连接完成后返回一个Folder
对象
connect 连接属性
属性 | 说明 |
---|---|
host | 服务器地址 |
port | 端口号 |
user | 邮箱 |
password | 密码 | 授权码 |
Folder
Folder inbox = store.getFolder("INBOX");
// 选择以什么方式打开
inbox.open(Folder.READ_ONLY);
// 获取服务器里全部的有邮件
Message[] messages = inbox.getMessages();
Folder常用方法
连接和断开
open(int mode)
:打开文件夹以进行读取和写入操作mode参数可以是Folder.READ_ONLY或Folder.READ_WRITEisOpen()
:检查文件夹是否已经打开getMode()
:获取文件夹的打开模式
关闭文件夹
close(boolean expunge)
:关闭文件夹并可选择是否清除已删除的邮件
获取邮件列表
getMessages()
:获取文件夹中的所有邮件getMessage(int msgnum)
:获取指定消息号的邮件,索引从 1 开始
搜索邮件
search(SearchTerm term)
:根据给定的搜索条件搜索邮件
创建、删除和重命名文件夹
create(int type)
:创建文件夹,type可以是HOLDS_MESSAGES或HOLDS_FOLDERSdelete(boolean recurse)
:删除文件夹,如果recurse为true,则递归删除子文件夹renameTo(Folder f)
:将文件夹重命名为给定的文件夹
其他方法
getFullName()
:获取文件夹的全名list(String pattern)
:列出文件夹的子文件夹getType()
:获取文件夹的类型,如HOLDS_MESSAGES或HOLDS_FOLDERS
getFolder 属性
属性 | 说明 |
---|---|
INBOX | 收件箱 |
Sent | 已发送邮件 |
Drafts | 草稿箱 |
Trash | 垃圾箱 |
Junk | 垃圾邮件文件夹 |
Archive | 归档文件夹 |
Spam | 垃圾邮件文件夹 |
Deleted Items | 已删除项目 |
All Mail | 所有邮件 |
Important | 重要邮件 |
Starred | 加星标邮件 |
Outbox | 发件箱 |
CustomFolderName | 自定义文件夹名称 |
对于POP3协议只有一个名为INBOX的Folder有效,而对于IMAP协议,我们可以访问多个Folder
open 属性
属性 | 说明 |
---|---|
Folder.READ_ONLY | 表示以只读模式打开邮件文件夹 |
Folder.READ_WRITE | 表示以读写模式打开邮件文件夹 |
Flags.Flag.RECENT | 表示邮件标记为最近收到的 |
Flags.Flag.SEEN | 表示邮件已被查看 |
Flags.Flag.DRAFT | 表示邮件是草稿 |
Flags.Flag.DELETED | 表示邮件已被标记为删除 |
Flags.Flag.ANSWERED | 表示邮件已被回复 |
Flags.Flag.FLAGGED | 表示邮件被标记 |
标志存在并非意味着这个标志被所有的邮件服务器所支持,例如:对于删除邮件的操作,POP协议不支持上面的任何一个,所以要确定哪些标志是被支持的通过访问一个已经打开的Folder对象的
getPermanetFlags()
方法,它将返回当前被支持的Flags类对象删除邮件时,我们可以设置邮件的DELETED标志:
message.setFlag(Flags.Flag.DELETED, true)
,但是首先要采用READ_WRITE
的方式打开Folder在对邮件进行删除操作后关闭Folder时,需要传递一个true作为对删除邮件的擦除确认:
folder.close(true)
检查某个标志是否被设置的方法:
Message.isSet(Flags.Flag flag)
,其中参数为被检查的标志
邮件内容解析
方法 | 说明 |
---|---|
message.getFrom() | 获取发件人 |
message.getRecipients(Message.RecipientType.TO)) | 获取收件人 |
message.getRecipients(Message.RecipientType.CC)) | 获取抄送者 |
message.getRecipients(Message.RecipientType.BCC)) | 获取密送着 |
message.getSubject() | 获取邮件主题 |
message.getSentDate() | 获取发送时间 |
message.getReceivedDate() | 获取接收时间 |
MIME 类型
类型 | 说明 |
---|---|
text/plain | 纯文本 |
text/html | HTML 文档 |
image/jpeg | JPEG 图像 |
image/png | PNG 图像 |
application/pdf | PDF 文档 |
application/json | JSON 数据 |
application/xml | XML 数据 |
audio/mpeg | MP3 音频 |
video/mp4 | MP4 视频 |
isMimeType(String mimeType)
方法来检查邮件的内容类型是否符合特定的 MIME 类型
Message
有两种方法可以读取邮件,分别是getContent()
与writeTo()
getContent()
方法只接收邮件内容,不包含邮件头writeTo()
包含邮件头
Authenticator 认证
JavaMail API也可以利用 Authenticator 通过用户名和密码访问受保护的资源。JavaMail Authenticator 在javax.mail包中,而且它和Java.net 中同名的类
Authenticator
不同。要使用Authenticator
,先创建一个抽象类的子类,并从getPasswordAuthentication()
方法中返回PasswordAuthentication
实例。创建完成后,必需向 session 注册Authenticator
向配置文件中添加对应的属性
mail.smtp.user=邮箱名
mail.smtp.password=密码|授权码(自定义)
然后通过Java代码获取
public class MyAuthenticator extends Authenticator {
// 账号密码
private static String userName;
private static String password;
// 进行文件初始化
static {
try {
Properties pr = new Properties();
pr.load(MyAuthenticator.class.getResourceAsStream("/Mail.properties"));
userName = pr.getProperty("mail.smtp.user");
password = pr.getProperty("mail.smtp.password");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public MyAuthenticator() {
}
// 后续如果更改使用后续更改内容
public MyAuthenticator(String userName, String password) {
MyAuthenticator.userName = userName;
MyAuthenticator.password = password;
}
// 返回当前使用账号
public static String getUserName() {
return userName;
}
// 返回实例
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(userName, password);
}
}
邮件概述
协议
SMTP
简单邮件传输协议,用于发送电子邮件的传输协议
POP3
用于接收电子邮件的标准协议,因为是第三代所以一般称为POP3
IMAP
互联网消息协议,是POP3的替代协议
收件人类型
普通收件人(TO - "To")
这是邮件的主要收件人。邮件中所有的 TO 收件人地址都会被列出来,每个收件人都可以看到其他收件人的地址
抄送(CC - "Carbon Copy")
抄送是指将邮件发送给其他一些人,这些人可以被视为邮件的抄送收件人。通常情况下,抄送收件人不需要直接回复邮件。抄送的收件人可以看到邮件的其他抄送收件人和主要收件人
密件抄送(BCC - "Blind Carbon Copy")
密件抄送是一种特殊的抄送方式,收件人列表中的其他人看不到被密件抄送的人的邮件地址。这种方式常用于发送给一些人而不让其他人知道这些人的邮件地址
SpringBoot 邮件发送(outlook)
导入依赖包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
编写配置文件
spring:
mail:
username: xxxxxx@outlook.com
password: xxxxxxx
host: smtp.office365.com
port: 587
default-encoding: UTF-8
properties:
mail:
smtp:
starttls:
enable: true
auth: true
发送代码
@SpringBootTest
class LookingServerToPlayApplicationTests {
@Resource
private JavaMailSenderImpl javaMailSender;
@Value("${spring.mail.username}")
private String username;
@Test
void contextLoads() {
SimpleMailMessage message = new SimpleMailMessage();
message.setSubject("曦暮流年");
message.setText("hello world");
message.setTo("ximuliunian@outlook.com");
message.setFrom(username);
javaMailSender.send(message);
}
}