从 01 开始 从 01 开始
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • RSS
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金等
  • 职场规划
  • 关于离职
  • 杂谈
  • 📖 读书

    • 读书工具
    • 读书笔记
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档

晓林

程序猿,自由职业者,博主,英语爱好者,健身达人
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • RSS
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金等
  • 职场规划
  • 关于离职
  • 杂谈
  • 📖 读书

    • 读书工具
    • 读书笔记
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档
  • JavaSE

    • 我的 Java 学习路线
    • 安装 Java
    • Java数据类型

    • Java 多版本配置
    • 面向对象

    • Java核心类

    • IO

    • Java与时间

    • 异常处理

    • 哈希和加密算法

    • Java8新特性

    • 网络编程

      • TCP 编程
      • UDP 编程
      • 发送 Email
      • 接受邮件
        • 接受邮件的协议
        • 小结
      • HTTP 编程
      • RMI 远程调用
  • JavaSenior

  • JavaEE

  • JavaWeb

  • Spring

  • 主流框架

  • SpringMVC

  • SpringBoot

  • Java
  • JavaSE
  • 网络编程
2023-04-17
目录

接受邮件

# 接受邮件

发送 Email 的过程我们在上一节已经讲过了,客户端总是通过 SMTP 协议把邮件发送给 MTA。

接收 Email 则相反,因为邮件最终到达收件人的 MDA 服务器,所以,接收邮件是收件人用自己的客户端把邮件从 MDA 服务器上抓取到本地的过程。

# 接受邮件的协议

接收邮件使用最广泛的协议是 POP3:Post Office Protocol version 3,它也是一个建立在 TCP 连接之上的协议。POP3 服务器的标准端口是 110,如果整个会话需要加密,那么使用加密端口 995。

另一种接收邮件的协议是 IMAP:Internet Mail Access Protocol,它使用标准端口 143 和加密端口 993。IMAP 和 POP3 的主要区别是,IMAP 协议在本地的所有操作都会自动同步到服务器上,并且,IMAP 可以允许用户在邮件服务器的收件箱中创建文件夹。

JavaMail 也提供了 IMAP 协议的支持。因为 POP3 和 IMAP 的使用方式非常类似,我们简单介绍下 IMAP。

收取 Email 时,我们无需关心 POP3/IMAP 的协议底层,因为 JavaMail 提供了高层接口。

我们创建一个 mail2.properties:密码已脱敏

mail.imap.host=imap.qq.com
mail.imap.port=993
mail.imap.socketFactory.class=javax.net.ssl.SSLSocketFactory
mail.imap.socketFactory.port=993
mail.imap.username=peterjxl@qq.com
mail.imap.password=***
1
2
3
4
5
6

创建 Store 对象,并连接:

Properties properties = new Properties();
properties.load(new FileInputStream("src/chapter20/mail2.properties"));
String host = properties.getProperty("mail.imap.host");
String username = properties.getProperty("mail.imap.username");
String password = properties.getProperty("mail.imap.password");

URLName url = new URLName("imap", host, 993, "", username, password);
Session session = Session.getInstance(properties, null);
session.setDebug(true);
Store store = new IMAPStore(session, url);
store.connect();     // 连接服务器,不连接则会报错 jakarta.mail.MessagingException: Not connected
1
2
3
4
5
6
7
8
9
10
11

一个 Store 对象表示整个邮箱的存储,要收取邮件,我们需要通过 Store 访问指定的 Folder(文件夹),通常是 INBOX 表示收件箱:

// 获取收件箱:
Folder folder = store.getFolder("INBOX");
// 以读写方式打开:
folder.open(Folder.READ_WRITE);
// 打印邮件总数/新邮件数量/未读数量/已删除数量:
System.out.println("Total messages: " + folder.getMessageCount());
System.out.println("New messages: " + folder.getNewMessageCount());
System.out.println("Unread messages: " + folder.getUnreadMessageCount());
System.out.println("Deleted messages: " + folder.getDeletedMessageCount());
// 获取每一封邮件:
Message[] messages = folder.getMessages();
for (Message message : messages) {
    // 打印每一封邮件:
    printMessage((MimeMessage) message);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

当我们获取到一个 Message 对象时,可以强制转型为 MimeMessage,然后打印出邮件主题、发件人、收件人等信息:

void printMessage(MimeMessage msg) throws IOException, MessagingException {
    // 邮件主题:
    System.out.println("Subject: " + MimeUtility.decodeText(msg.getSubject()));
    // 发件人:
    Address[] froms = msg.getFrom();
    InternetAddress address = (InternetAddress) froms[0];
    String personal = address.getPersonal();
    String from = personal == null ? address.getAddress() : (MimeUtility.decodeText(personal) + " <" + address.getAddress() + ">");
    System.out.println("From: " + from);
    // 继续打印其他信息,例如收件人,正文.........
}
1
2
3
4
5
6
7
8
9
10
11

比较麻烦的是获取邮件的正文。一个 MimeMessage 对象也是一个 Part 对象,它可能只包含一个文本,也可能是一个 Multipart 对象,即由几个 Part 构成,因此,需要递归地解析出完整的正文:

String getBody(Part part) throws MessagingException, IOException {
    if (part.isMimeType("text/*")) {
        // Part是文本:
        return part.getContent().toString();
    }
    if (part.isMimeType("multipart/*")) {
        // Part是一个Multipart对象:
        Multipart multipart = (Multipart) part.getContent();
        // 循环解析每个子Part:
        for (int i = 0; i < multipart.getCount(); i++) {
            BodyPart bodyPart = multipart.getBodyPart(i);
            String body = getBody(bodyPart);
            if (!body.isEmpty()) {
                return body;
            }
        }
    }
    return "";
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

最后记得关闭 Folder 和 Store:

folder.close(true); // 传入true表示删除操作会同步到服务器上(即删除服务器收件箱的邮件)
store.close();
1
2

# 小结

使用 Java 接收 Email 时,可以用 POP3 协议或 IMAP 协议。

设置 debug 模式可以查看通信详细内容,便于排查错误。

上次更新: 2024/10/1 17:41:58
发送 Email
HTTP 编程

← 发送 Email HTTP 编程→

最近更新
01
吐槽一下《僵尸校园》
05-15
02
2025 年 4 月记
04-30
03
山西大同 “订婚强奸案” 将会给整个社会带来的影响有多严重? - 知乎 转载
04-26
更多文章>
Theme by Vdoing | Copyright © 2022-2025 | 粤 ICP 备 2022067627 号 -1 | 粤公网安备 44011302003646 号 | 点击查看十年之约
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式