email学习笔记

email学习笔记

邮件发送的基本过程与概念

邮件发送的过程

graph LR
    userA(("用户A
xx@qq.com")) userA--"1"-->clientA clientA["邮件客户端
FoxMail"] clientA--"2"-->qqServerModule2 subgraph QQ邮箱服务器 qqServerModule1("POP3服务器") qqServerModule2("SMTP服务器") qqServerModule3("QQ邮箱
内部存储空间") end qqServerModule2--"3"-->163ServerModule2 subgraph 163邮箱服务器 163ServerModule1("POP3服务器") 163ServerModule2("SMTP服务器") 163ServerModule3("163邮箱
内部存储空间") 163ServerModule2--"4"-->163ServerModule3 163ServerModule1--"7"-->163ServerModule3 163ServerModule3--"8"-->163ServerModule1 end userB(("用户B
xx@163.com")) userB--"5"-->clientB clientB["邮件客户端
FoxMail"] clientB--"6"-->163ServerModule1 163ServerModule1--"9"-->clientB clientB--"10"-->userB

1.用户A写完一封邮件通过客户端(如Foxmail)使用SMTP协议发送到邮箱的SMTP服务器
2.邮箱SMTP服务器收到邮件后会判断收件人是否是自己管辖内的账户
如果是就会直接放入自己的存储空间
如果不是就会通过SMTP协议发送给对应的对应地址的SMTP服务器
3.用户B通过客户端向POP3服务端服务器请求收取自己的邮件
4.POP3服务器收到请求之后查询内部存储空间
如果有邮件则通过POP3协议发送给用户B
如果没有就返回空

邮件传输协议

  • SMTP协议:全称为 Simple Mail Transfer Protocol,简单邮件传输协议
    它定义了邮件客户端软件和SMTP邮件服务器之间,以及两台SMTP邮件服务器之间的通信规则
  • POP3协议:全称为 Post Office Protocol,邮局协议
    它定义了邮件客户端软件和POP3邮件服务器的通信规则
  • IMAP协议:全称为 Internet Message Access Protocol,Internet消息访问协议
    它是对POP3协议的一种扩展,也是定义了邮件客户端软件和IMAP邮件服务器的通信规则

    邮件服务器于客户端

  • SMTP服务器:通过SMTP协议接收和发送邮件
  • POP3服务器:通过POP3协议发送邮件的服务器
  • 客户端:邮件客户端软件通常集邮件撰写/发送和收发功能于一体
    主要用于帮助用户将邮件发送给SMTP邮件服务器和从POP3/IMAP邮件服务器读取用户的电子邮件
    比如常见的FoxMail,Outlook Express

    手工体验smtp和pop3协议

    SMTP简介

    SMTP协议:全称为 Simple Mail Transfer Protocol,简单邮件传输协议.它定义了邮件客户端软件和SMTP邮件服务器之间,以及两台SMTP邮
    件服务器之间的通信规则
    SMTP协议的通信双方采用一问一答的命令/响应形式进行对话
    SMTP协议分为标准SMTP协议和扩展SMTP协议

    标准SMTP协议是1982年在RFC821 文档中定义的
    扩展SMTP协议是1995年在RFC1869 文档中定义的

    扩展SMTP协议在标准 SMTP协议基础上的改动非常小,主要增加了邮件安全方面的认证功能,现在我们说的SMTP协议基本上都是扩展SMTP协议

参考文档:https://tools.ietf.org/html/rfc1869

SMTP协议中的命令

SMTP 协议中一共定义了18条命令
但是发送一封电子邮件的过程通常只需要6条命令

SMTP命令及格式
<SP>表示空格
<CRLF>表示回车换行
说明
ehlo<SP><domain><CRLF> ehlo命令是SMTP邮件发送程序与SMTP邮件接收程序建立连接后必须发送的第一条SMTP命令,参数<domain>表示SMTP邮件发送者的主机名,ehlo命令用于代替传统命令中的helo命令
auth<SP><para><CRLF> 如果SMTP邮件接收程序需要SMTP邮件发送程序进行认证时,他向SMTP邮件发送程序提示它所采用的认证方式,SMTP邮件发送程序接着应该使用这个命令回应SMTP邮件接收程序,参数<para>表示回应的认证方式,通常是SMTP邮件接收程序先提示的认证方式
mail<SP>from:<reverse-path><CRLF> 此命令用于指定邮件发送者的邮箱地址,参数<reverse-path>表示邮件发送人的邮箱地址
rcpt<SP>to:<froword-path><CRLF> 此命令用于指定邮件接收者的邮箱地址,参数<forword-path>表示收件人的邮箱地址,
如果邮件要发送给多个接受者,那么应该使用多条rcpt<SP>to命令来分别指定每一个接受者的邮箱地址
data<CRLF> 此命令用于表示SMTP邮件发送程序开始传动邮件内容,在这命令后面发送的所有数据都被当成邮件内容,直到遇见”<CRLF>.<CRLF>“标识符,则表示邮件内容结束
quit<CRLF> 此命令表示要借宿邮件发送过程,SMTP邮件接收程序接收到此命令后将关闭与SMTP邮件服务器的连接

手动发送过程

graph LR
    root(使用SMTP协议手工发送邮件的步骤)
    root---step1("1.和SMTP服务器建立连接:
telnet smtp.163.com 25") root---step2("2.ehlo 邮件发送者用户名") root---step3("3.选择登陆认证方式") root---step4("4.分别输入经过Base64编码后的用户名和密码") root---step5("5.指明邮件的发送人和收件人") root---step6("6.编写邮件内容") root---step7("7.输入.表示邮件内容结束") root---step8("8.输入quit命令断开与邮件服务器的连接")

解释:

  1. 如果是qq,那么就将163换成qq即可,25换成587,25或者587是端口,其他邮箱同理
  2. 告诉SMTP服务器发送者的用户名
  3. 登录认证方式,我们一般使用login,即输入命令:auth:login qq邮箱需要先输入 starttls
  4. qq邮箱需要的是进过Base64编码的授权码

5.6.7.8. 没有什么坑,按照范例来就好

qq邮箱范例:

括号内的为备注

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
telnet smtp.qq.com 587

ehlo 1336789387@qq.com (账号1336789387也可以)

starttls

auth login

MTMzNjc4OTM4N0BxcS5jb10= (1336789387@qq.com)

bWR4eWt0eGthdmhoamFiYg== (mdxyktxkavhyjacb)

mail from:<1336789387@qq.com>

rcpt to:<1791738789@qq.com>

data

from:<1336789387@163.com>
to:<1791738789@qq.com>
subject:hello world
This is the first email sent by hand using the SMTP protocol
.

quit

手动接收邮件

graph LR
    root(使用SMTP协议手工接收邮件的步骤)
    root---step1("1.和SMTP服务器建立连接:
telnet pop3.163.com 110
telnet pop.qq.com 110") root---step2("2.user 用户名 qq要求必须是邮箱") root---step3("3.pass 密码 qq是授权码") root---step4("4.其他各种查看服务器邮件的命令") root---step5("8.输入quit命令断开与邮件服务器的连接")

qq邮箱范例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
telnet pop.qq.com 110

user 1336789387@qq.com

pass mdxyktxkavhyjacb

stat

list

retr 1

dele 1

noop

quit

这里有个比较坑的地方就是user和pass这一块的内容必须一次性的输入正确,不能修改,修改对了也没有用

相关命令详解

SMTP命令及格式
<SP>表示空格
<CRLF>表示回车换行
说明
user<SP>username<CRLF> user命令是POP3客户端程序与POP3邮件服务器建立后发送的第一条命令,参数username表示收件人的人账户名称(这里用原来的就好)
pass<SP>password<CRLF> pass命令是在user命令执行成功后接着发送的命令,参数password表示账户密码
stat<CRLF> stat命令用于查询邮箱统计信息,后面的两个数字表示邮件的数目和占用字节大小(不过qq邮箱网页上的和我在这里看到不太一样)
list<SP>[msg#]<CRLF> list命令用于查出邮箱中邮件信息,msg#表示邮件序列号,是可选参数.当不指定时列出所有的邮件信息,
uidl<SP>msg#<CRLF> uidl命令查询谋一份邮件的唯一标识,参数msg#表示邮件序列号
retr<SP>msg#<CRLF> retr命令获取某一封邮件内容,参数msg#表示邮件序列号
dele<SP>msg#<CRLF> dele命令用于标记删除某一封邮件,不是立刻真的删除,只有执行quit命令退出POP3邮件服务器时才会真的删除
rest<CRLF> rest命令用于清除所有删除标记
top<SP>msg#<SP>n<CRLF> top命令用于获取序号为msg的邮件前n行内容
noop<CRLF> noop命令用于检查POP3客户端与服务器的连接情况
quit<CRLF> quit命令用于借宿邮件接收过程,执行此命令,POP3服务器会删除所有标记了的邮件,关闭与POP3客户端的连接

邮件内容详解

邮件遵循RFC822文档和MIME协议

RFC822文档定义邮件的基本格式
MIME协议定义邮件的具体细节

范例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Received: from vip.ccb.com (unknown [113.57.178.241])
by newmx39.qq.com (NewMx) with SMTP id
for <1336789387@qq.com>; Sat, 28 Dec 2019 01:59:54 +0800
X-QQ-FEAT: y37167hFrfVEjfHxpsOqS0boY0Vv3hbEhRXmhYgWrdM=
X-QQ-MAILINFO: ObpyOLNbESSk6OKd+DJ9/SHErARu1daO07Kw4PHkAhFMqO8mEbRL9OPln
bBpOLdhxg4YyNui535W6lHS6XpwZUJYRHJsRYzIS2zDaJ900f11Te2232kOFguri7SIYYtg
MxIxPsHQzoNF/gVGOGWEMYuLf+aromZ3kkufi4DWIjV+
X-QQ-mid: mx39t1577469594tdvvbsvsj
X-QQ-ORGSender: service@vip.ccb.com
X-QQ-XMAILINFO: OOAQOIAXcEJZWtGNNSzEy+/cE5za9lGv9S6nNmLJgg8mjG8dILRN0+UW6kKnt8
CaeqcGtCmzJUsvGnm8+NCDjjv95/FchyxN6UcPWfJiKhf4T9tUud7fkdlbpuraBBT0XZY/tvljzv
UovxYCs216edCXOr0BQNzlELzwjga697XTmZd+bd9AzzxcqcirvXTK3DC7KynIRqma7+/jx1+j+i
FXM/1H67yliT0M2mVuQ5vp5VluFOnGN55e+VHU3bU5ZU5fc36JAm93jDl68HtKj+Wlsi0EfI8Svu
Rqdyzrzdo2d4hAfPLdVV4lEK//DAQIGvAlRRBN5gpE3WE/d66kIMcjz+ANFV+fJN/tcn6qJF5bm7
SUErgCH42JToWZusC9vKJJjfiY0NlA3413ynEdjG6iFj0efHrAga5/RHrScBg1rA3Jv31QubpcHF
6aL6ZCAJE9rx/IMsvQck7WarJfjJnu6ExOJM8v1+hKMs5v3tbSKvrn15c697AfOT5G0LjyTQlXPn
QnaIL7veBi4fJLMGoaWlhNqrJHLrk+BzLe9n53q5TVHrUPlYYkbGMakzOdjAoWATkhEawtvVtWAt
Qv+dTOPEQLi/RDxdnVdrhu6XNYzj7UCBzgMTFXBh78hCEu5P0dPcaFDNx8Rqt/3GTVo7z4I+3iSb
/0mILB04/TBXFrJ+CAXssYnDZ9QQ28Tvv4TG0mb2COZBXm1f6ifuRnXQIfidzfT8cJ3aAQp31u6H
HSxrvThOV1Bzw=
Message-ID: <1516679348.15251577397823338.JavaMail.ncismigbat@by18cisplap2003>
Date: Sat, 28 Dec 2019 01:59:53 +0800 (CST)
From: service@vip.ccb.com
To: 1336789387@QQ.COM
Subject: =?GBK?B?1tC5+r2oyejS+NDQ0MXTw7+otefX09XLtaU=?=
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="----=_Part_1525_1669750793.1577397823338"

------=_Part_1525_1669750793.1577397823338
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: base64

PCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMDEgVHJhbnNpdGlvbmFs
Ly9FTiIgImh0dHA6Ly93d3cudzMub3JnL1RSL2h0bWw0L2xvb3NlLmR0ZCI+CjxodG1sPgogPGhl
YWQ+CiAgPHRpdGxlPiDkuK3lm73lu7rorr7pk7booYzkv6HnlKjljaHpvpnljaHkv6HnlKjljaHl
r7notKbljZUgPC90aXRsZT4KICA8bWV0YSBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNvbnRl

.

RFC822文档

RFC822由邮件头和邮件组成
邮件头字段|说明
—|—
Received|该字段基本格式为Received: from A by B for C,A为发送方,B为接收方,C为吉首人邮箱地址.由SMTP服务器填写
From|发件人邮件地址,邮件阅读器中发件人地址来源于此,可以乱写,可以不写,可以伪造.所以发件人不一定为真的
To|收件人地址
Subject|指定邮件主题,如果主题内容中包含ASCII码以外的字符,通常要对其内容编码
cc|邮件抄送地址
bcc|邮件密送地址,邮件阅读器通常不会显示密送地址,而会显示抄送地址

BRC822文档的两个问题:
  1. 定义了邮件的主体结构和邮件有地段的详细细节,但是没有定义邮件提的格式,RFC822文档定义的邮件体部分通常都只能用于表述一段普通的文本,而无法表达出图片/声音等二进制数据
  2. SMTP服务器在接收邮件内容是当收到单行.时会认为邮件已接收,可能造成内容缺失
    MIME解决了这两个问题

    MIME协议

  • 全称:Multipurpose Internet Mail Extension(协议)
  • 中文翻译:多用途因特网邮件扩展(协议)
    1
    2
    3
    4
    5
    6
    7
    Subject: =?GBK?B?1tC5+r2oyejS+NDQ0MXTw7+otefX09XLtaU=?=
    MIME-Version: 1.0
    Content-Type: multipart/mixed; boundary="----=_Part_1525_1669750793.1577397823338"

    ------=_Part_1525_1669750793.1577397823338
    Content-Type: text/html; charset=utf-8
    Content-Transfer-Encoding: base64

一个采用了MIME协议的电子邮件就叫做MIME邮件
MIME邮件在RFC822文档中定义的邮件头字段的基础上,扩充了一些自己专用的邮件头字段,例如:

使用MIME-Version头字段指定MIME协议的版本
使用Content-Type头字段指定邮件体的MIME类型
使用Content-Transfer-Encoding头字段指定编码方法

其中,“multipart/mixed”部分说明邮件体中包含有多段数据,每段数据之间使用boundary属性中指定的字符文本作为分隔标识符
MIME邮件也扩展了RFC822文档中已经定义了的邮件头字段的内涵,例如:

定义了subject头字段中的值内容的格式,以便通过编码的方式让邮件主题中也可以使用非ASCII码的字符
subject头字段中的值嵌套在一对=??=标记符之间,标记符之间的内容由三部分组成:

  • 邮件主题的原始内容的字符集
  • 当前采用的编码方式
  • 编码后的结果

这三部分之间使用?进行分隔

JavaMail发送(带图片和附件)和接收邮件

JavaMail介绍

JavaMail是sun公司(现以被甲骨文收购)为方便Java开发人员在应用程序中实现邮件发送和接收功能而提供的一套标准开发包
它支持一些常用的邮件协议,如前面所讲的SMTP,POP3,IMAP,还有MIME等
我们在使用JavaMail API 编写邮件时,无须考虑邮件的底层实现细节,只要调用JavaMail开发包中相应的API类就可以了

JavaMail API

JavaMail API按照功能可以分为三大类:

  • 创建和解析邮件的API
  • 发送邮件的API
  • 接收邮件的API
graph LR
session1["Session对象:
定义整个程序所需环境信息,
比如主机名,端口号采用的邮件发送和接收的协议"] session1--创建-->transport transport["Transport对象:
用来发送邮件"] message1["Message对象:
表示一份电子邮件"] message1-.引用.->transport transport==>server server(("邮件服务器")) server==>store store["Store对象:
用来接收邮件"] session2["Session对象:
定义整个程序所需环境信息,
比如主机名,端口号采用的邮件发送和接收的协议"] session2--创建-->store store--创建-->message2 message2["Message对象:
表示一份电子邮件"]

以上三种类型的API由多个类组成,其中核心的由四个类:

  • Message类:javax.mail.Message类是创建和解析邮件的核心API,这是一个抽象类,通常使用它的子类javax.mail.internet.MimeMessage类.它的实例对象表示一份电子邮件.客户端程序发送邮件时,首先使用创建邮件的JavaMail API创建出封装了邮件数据的Message对象,然后把这个对象传递给邮件发送APITransport 类发送.客户端程序接收邮件时,邮件接收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对象时提供信息支持.

相关jar包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

<dependencies>
<!-- javaMailAPI -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>1.6.2</version>
</dependency>
<!-- javaMailAPI的一种实现 -->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
</dependencies>

在引入javaMailAPI的同时还需要引入他的实现

使用JavaMailAPI实现发送和接收邮件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
package util;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.util.Date;
import java.util.Properties;

public class EmailTest {
//发件人地址
public static String senderAddress = "1336789387@qq.com";
//发件人账户名
public static String senderAccount = "1336789387@qq.com";
//发件人账户密码
public static String senderPassword = "jbiykarygvkbhi";

//收件人地址
public static String recipientAddress = "1791738789@qq.com";
//收件人账户名
public static String recipientAccount = "1791738789@qq.com";
//收件人账户密码
public static String recipientPassword = "jbiykarygvkbhi";

/**
* 发送邮件
*
* @throws Exception
*/
public static void sendEmail() throws Exception {
//1、连接邮件服务器的参数配置
Properties props = new Properties();
//设置用户的认证方式
props.setProperty("mail.smtp.auth", "true");
//设置传输协议
props.setProperty("mail.transport.protocol", "smtp");
//设置发件人的SMTP服务器地址
props.setProperty("mail.smtp.host", "smtp.qq.com");
//2、创建定义整个应用程序所需的环境信息的 Session 对象
Session session = Session.getInstance(props);
//设置调试信息在控制台打印出来
session.setDebug(true);
//3、创建邮件的实例对象
Message msg = getMimeMessage(session);
//4、根据session对象获取邮件传输对象Transport
Transport transport = session.getTransport();
//设置发件人的账户名和密码
transport.connect(senderAccount, senderPassword);
//发送邮件,并发送到所有收件人地址,message.getAllRecipients() 获取到的是在创建邮件对象时添加的所有收件人, 抄送人, 密送人
transport.sendMessage(msg, msg.getAllRecipients());
//5、关闭邮件连接
transport.close();
}

/**
* 获得创建一封邮件的实例对象
*
* @param session
* @return
* @throws Exception
*/
public static MimeMessage getMimeMessage(Session session) throws Exception {
//1.创建一封邮件的实例对象
MimeMessage msg = new MimeMessage(session);
//2.设置发件人地址
msg.setFrom(new InternetAddress(senderAddress));
/**
* 3.设置收件人地址(可以增加多个收件人、抄送、密送),即下面这一行代码书写多行
* MimeMessage.RecipientType.TO:发送
* MimeMessage.RecipientType.CC:抄送
* MimeMessage.RecipientType.BCC:密送
*/
msg.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(recipientAddress));
//4.设置邮件主题
msg.setSubject("邮件主题(包含图片和附件)", "UTF-8");

//下面是设置邮件正文
//msg.setContent("简单的纯文本邮件!", "text/html;charset=UTF-8");

// 5. 创建图片"节点"
MimeBodyPart image = new MimeBodyPart();
// 读取本地文件
DataHandler dh = new DataHandler(new FileDataSource("src\\mailTestPic.png"));
// 将图片数据添加到"节点"
image.setDataHandler(dh);
// 为"节点"设置一个唯一编号(在文本"节点"将引用该ID)
image.setContentID("mailTestPic");

// 6. 创建文本"节点"
MimeBodyPart text = new MimeBodyPart();
// 这里添加图片的方式是将整个图片包含到邮件内容中, 实际上也可以以 http 链接的形式添加网络图片
text.setContent("这是一张图片<br/>" +
"<a href='https://rescdn.qqmail.com/zh_CN/htmledition/images/spacer1e9c5d.gif'>" +
" <img src='cid:mailTestPic'/>" +
"</a>",
"text/html;charset=UTF-8");

// 7. (文本+图片)设置 文本 和 图片"节点"的关系(将 文本 和 图片"节点"合成一个混合"节点")
MimeMultipart mm_text_image = new MimeMultipart();
mm_text_image.addBodyPart(text);
mm_text_image.addBodyPart(image);
mm_text_image.setSubType("related"); // 关联关系

// 8. 将 文本+图片 的混合"节点"封装成一个普通"节点"
// 最终添加到邮件的 Content 是由多个 BodyPart 组成的 Multipart, 所以我们需要的是 BodyPart,
// 上面的 mailTestPic 并非 BodyPart, 所有要把 mm_text_image 封装成一个 BodyPart
MimeBodyPart text_image = new MimeBodyPart();
text_image.setContent(mm_text_image);

// 9. 创建附件"节点"
MimeBodyPart attachment = new MimeBodyPart();
// 读取本地文件
DataHandler dh2 = new DataHandler(new FileDataSource("src\\mailTestDoc.docx"));
// 将附件数据添加到"节点"
attachment.setDataHandler(dh2);
// 设置附件的文件名(需要编码)
attachment.setFileName(MimeUtility.encodeText(dh2.getName()));

// 10. 设置(文本+图片)和 附件 的关系(合成一个大的混合"节点" / Multipart )
MimeMultipart mm = new MimeMultipart();
mm.addBodyPart(text_image);
mm.addBodyPart(attachment); // 如果有多个附件,可以创建多个多次添加
mm.setSubType("mixed"); // 混合关系

// 11. 设置整个邮件的关系(将最终的混合"节点"作为邮件的内容添加到邮件对象)
msg.setContent(mm);
//设置邮件的发送时间,默认立即发送
msg.setSentDate(new Date());

return msg;
}


/**
* 接收邮件
*
* @throws Exception
*/
public static void recipientMail() throws Exception {
//1、连接邮件服务器的参数配置
Properties props = new Properties();
//设置传输协议
props.setProperty("mail.store.protocol", "pop3");
//设置收件人的POP3服务器
props.setProperty("mail.pop3.host", "pop.qq.com");
//2、创建定义整个应用程序所需的环境信息的 Session 对象
Session session = Session.getInstance(props);
//设置调试信息在控制台打印出来
//session.setDebug(true);

Store store = session.getStore("pop3");
//连接收件人POP3服务器
store.connect("pop.qq.com", recipientAccount, recipientPassword);
//获得用户的邮件账户,注意通过pop3协议获取某个邮件夹的名称只能为inbox
Folder folder = store.getFolder("inbox");
//设置对邮件账户的访问权限
folder.open(Folder.READ_WRITE);

//得到邮件账户的所有邮件信息
Message[] messages = folder.getMessages();
for (int i = 0; i < messages.length; i++) {
//获得邮件主题
String subject = messages[i].getSubject();
System.out.println("subject = " + subject);
//获得邮件发件人
Address[] from = messages[i].getFrom();
//获取邮件内容(包含邮件内容的html代码)
String content = (String) messages[i].getContent();
}

//关闭邮件夹对象
folder.close();
//关闭连接对象
store.close();
}

}

本文章参考[YSOcean博客][YSOcean博客]
https://www.cnblogs.com/ysocean/p/7652934.html
https://www.cnblogs.com/ysocean/p/7653252.html


坚持原创技术分享,您的支持将鼓励我继续创作!