在网络上,想要实现邮件功能,必须要有专门的邮件服务器,这些服务器类似于我们生活中的邮局,快递站等等。它负责接收邮件并将邮件投递到邮件接收者的邮箱中。
┌─────────┐ ┌─────────┐ ┌─────────┐
│░░░░░░░░░│ │░░░░░░░░░│ │░░░░░░░░░│
┌───────┐ ├─────────┤ ├─────────┤ ├─────────┤ ┌───────┐
│░░░░░░░│ │░░░░░░░░░│ │░░░░░░░░░│ │░░░░░░░░░│ │░░░░░░░│
├───────┤ ├─────────┤ ├─────────┤ ├─────────┤ ├───────┤
│ │───>│O ░░░░░░░│───>│O ░░░░░░░│───>│O ░░░░░░░│<───│ │
└───────┘ └─────────┘ └─────────┘ └─────────┘ └───────┘
MUA MTA MTA MDA MUA
MUA代表了给用户服务的邮件代理;邮件服务器则称为MTA,它是邮件中转的代理,也就是我们日常生活中的邮局;最终到达的邮件服务器称为MDA,电子邮件一旦到达MDA就不会再动了。实际上,电子邮寄一般存储在MDA服务器的硬盘上,等待收件人通过客户端或者网页来查看邮件。
在这里,我们需要认识几种传输协议:
POP3(Post Office Protocol 3):是邮局协议的第三个版本,它规定将个人PC连接到Internet的邮件服务器和下载电子邮件的电子协议。POP3允许用户从服务器上把邮件存储到本地主机中,并且删除保存在邮件服务器上的邮件。
SMTP(Simple Mail Transfer Protocol):即简单邮件传输协议。它是一组用于从源地址到目的地址传输邮件的规范,通过它来控制邮件的中转方式,SMTP协议属于TCP/IP协议簇。SMTP服务器就是遵循SMTP协议的发送邮件服务器。
IMAP(Internet Mail Access Protocol):即交互式邮件存储协议,它与POP3协议一样,都是用来发送邮件的标准协议之一。但是与POP3不同的是,开启了IMAP后,你在客户端收取的邮件仍然保留在服务器上,同时所有的操作都会回馈给服务器。
假设我们准备使用自己的邮件地址发送邮件,在发送邮件前,我们首先要确定作为MTA的邮件服务器地址和端口号,邮件服务器的地址通常是smtp.***.com,端口号由邮件服务商确定。接着,我虚需要将JavaMail相关的依赖jar包加入到当前项目。
然后我们通过JavaMail API连接到SMTP服务器上,连接SMTP服务器时,需要准备一个Properties对象,填入相关信息,然后获取Session实例。当我们获取到Session实例后,打开debug模式便于我们查看SMTP通信的详细内容。
// 服务器地址:
String smtp = "smtp.126.com";
// 登录用户名:
String username = "XXXXXXXX@126.com";
// 登录口令:
String psw = "******************";
// 连接到SMTP服务器25端口:
Properties props = new Properties();
props.put("mail.smtp.host", smtp); // SMTP主机名
props.put("mail.smtp.port", "25"); // 主机端口号
props.put("mail.smtp.auth", "true"); // 是否需要用户认证
props.put("mail.smtp.starttls.enable", "true"); // 启用TLS加密
// 获取Session实例:
Session session = Session.getInstance(props, new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
// 设置debug模式便于调试:
session.setDebug(true);
发送邮件时,我们需要构造一个Message对象,然后调用Transport.send(Message)即可完成发送。
try {
MimeMessage message = new MimeMessage(session);
// 设置发送方地址:
message.setFrom(new InternetAddress("XXXXXXXX@126.com"));
// 设置接收方地址:
message.setRecipient(Message.RecipientType.TO, new InternetAddress("********@qq.com"));
// 设置邮件主题:
message.setSubject("Hello", "UTF-8");
// 设置邮件正文:
message.setText("Hi Xiaoming...", "UTF-8");
// 发送:
Transport.send(message);
} catch (AddressException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
}
运行上边代码后,我们可以在控制台看到JavaMail打印的调试信息:
如果我们想在邮件中附带的发送附件,例如图片、音频等,我们就不能直接调用message.setText()方法,而是要构造Multipart对象:
// 创建MimeMessage邮件信息对象
// ...略
// 创建Multipart复合对象
Multipart multipart = new MimeMultipart();
// 添加text:
BodyPart textpart = new MimeBodyPart();
textpart.setContent(body, "text/html;charset=utf-8");
multipart.addBodyPart(textpart);
// 添加image:
BodyPart imagepart = new MimeBodyPart();
imagepart.setFileName(附件名称);
imagepart.setDataHandler(new DataHandler(new ByteArrayDataSource(文件流字节数组, "application/octet-stream")));
multipart.addBodyPart(imagepart);
// 设置邮件内容为multipart:
message.setContent(multipart);
一个Multipart对象可以添加若干个BodyPart,其中一个是文本,后面一个是附件。BodyPart依靠setContent()决定添加内容,如果内容为纯文本,则用setContent(“***”,“text/plain;charset=utf-8”).如果添加附件,需要设置文件名,并且添加一个DataHandler(),传入文件的MIME类型。最后,通过setContent()把Multipart添加到Message中,即可发送。