Skip to content

使用Maven进行导包

基础包:

xml
<!-- JavaMail基本包 -->
<dependency>
 <groupId>javax.mail</groupId>
 <artifactId>mail</artifactId>
 <version>1.5.0-b01</version>
</dependency>

框架包:

xml
<!-- 邮件发送的扩展包 -->
<dependency>
 <groupId>javax.activation</groupId>
 <artifactId>activation</artifactId>
 <version>1.1</version>
</dependency>

此框架增加了对任何数据块的分类、以及对它们的处理的特性

注意:activation扩展包在Java6之后已经合并到了JDK中,而JDK5之前需要另外下载扩展包

Properties属性认证

两种使用方式,一种是直接在对象里面使用(不推荐),还有是定义一个配置文件(Mail.properties)把属性存放到文件里面(推荐)

属性名属性类别说明
mail.smtp.hostStringSMTP服务器地址
mail.smtp.portintSMTP服务器端口号,默认25
mail.smtp.authbooleanSMTP服务器是否需要用户认证,默认false
mail.smtp.userStringSMTP默认登陆用户名
mail.smtp.fromString默认的邮件发送源地址
mail.smtp.socketFactory.classStringsocket工厂类,通过设置该属性可以覆盖提供者默认的实现,必须实现javax.NET.SocketFactory接口
mail.smtp.socketFactory.portint指定socket工程类所用的端口号,默认使用默认的端口号
mail.smtp.socketFactory.fallbackboolean设置为true时,当使用指定的socket类创建socket失败后,将使用Java.net.Socket创建socket,默认为true
mail.smtp.timeoutint连接超时时间,单位为毫秒,默认永不超时

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邮箱)

properties
mail.smtp.host=smtp.qq.com
mail.smtp.port=587
mail.smtp.auth=true

然后通过代码获取

java
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 对象,需要根据邮件的类型进行类型转换

发送两种邮件

纯邮件

java
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的方式进行发送邮件,这会使邮件变得更精美

需要有两种对象:MultipartBodyPart

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 的数量
代码
java
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);
添加附件
java
BodyPart bodyPart = new MimeBodyPart();
bodyPart.setFileName("文件名");
bodyPart.setDataHandler(new DataHandler(new FileDataSource(new File("文件路径"))));

在添加文件名的时候使用中文可能会出现乱码情况,这是因为跟服务器编码不统一所导致的,只需要在里面再套一层即可 bodyPart.setFileName(MimeUtility.encodeText("文件名"))

Address 地址

有了SessionMessage两个对象后,可以使用AddRess来确定双方的地址,这也是一个抽象类,一般使用InternetAddress

java
new InternetAddress("邮件地址")

Transport 发送

邮件有发送和接收两种操作,Transport进行邮件发送,Store进行邮件的接收

方法作用
send()发送邮件(静态)

Store&Folder 收取&内容

读取完邮件后关闭Store&Folder

Store

session会话使用getStore("pop3 | imap")方法获取并连接到Store(邮件服务器)

java
// MailUtils 为编写的工具类
Store store = MailUtils.getSession().getStore("pop3 | imap");
// 建立连接
store.connect(host,port,user,password);

连接完成后返回一个Folder对象

connect 连接属性

属性说明
host服务器地址
port端口号
user邮箱
password密码 | 授权码

Folder

java
Folder inbox = store.getFolder("INBOX");
// 选择以什么方式打开
inbox.open(Folder.READ_ONLY);
// 获取服务器里全部的有邮件
Message[] messages = inbox.getMessages();

Folder常用方法

连接和断开

open(int mode):打开文件夹以进行读取和写入操作mode参数可以是Folder.READ_ONLY或Folder.READ_WRITE isOpen():检查文件夹是否已经打开 getMode():获取文件夹的打开模式

关闭文件夹

close(boolean expunge):关闭文件夹并可选择是否清除已删除的邮件

获取邮件列表

getMessages():获取文件夹中的所有邮件 getMessage(int msgnum):获取指定消息号的邮件,索引从 1 开始

搜索邮件

search(SearchTerm term):根据给定的搜索条件搜索邮件

创建、删除和重命名文件夹

create(int type):创建文件夹,type可以是HOLDS_MESSAGES或HOLDS_FOLDERS delete(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/htmlHTML 文档
image/jpegJPEG 图像
image/pngPNG 图像
application/pdfPDF 文档
application/jsonJSON 数据
application/xmlXML 数据
audio/mpegMP3 音频
video/mp4MP4 视频

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

向配置文件中添加对应的属性

properties
mail.smtp.user=邮箱名
mail.smtp.password=密码|授权码(自定义)

然后通过Java代码获取

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)

导入依赖包

xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

编写配置文件

yml
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

发送代码

java
@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);
    }

}