本篇文章记录小Z在学习使用JAVA Mail API发送邮件的代码过程
首先,小Z的需求是希望发送一封邮件到自己的QQ邮箱中,当然还是通俗易懂的Hello World。
需要开启QQ邮箱中的设置,开启POP3/SMTP服务
根据要求发送短信到腾讯科技,配置邮件客户端,随后您会获得授权码,该授权码用于之后的代码配置。
进行代码编写,新建一个MAVEN项目,需要下一个包:
<!-- https://mvnrepository.com/artifact/javax.mail/mail -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
javax.mail 最近版本1.4.7
新建一个Mail类,代码如下:
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
public class Mail {
public static void sendMail() throws MessagingException{
Properties props = new Properties();
props.setProperty("mail.smtp.host", "smtp.qq.com");
props.setProperty("mail.transport.protocol", "smtp");
props.setProperty("mail.smtp.auth", "true");
//设置ssl的端口
props.setProperty("mail.smtp.port", "465");
props.setProperty("mail.smtp.ssl.enable", "true");
Authenticator auth = new MailAuthenticator();
Session session = Session.getInstance(props,auth);
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress("sample@qq.com"));
msg.setSubject("Hello World");
msg.setText("It is a happy way to learn java");
msg.setRecipient(RecipientType.TO, new InternetAddress("sample@qq.com"));
Transport.send(msg);
System.out.println("SUCCESS");
}
}
其中,发送邮件给企鹅邮箱需要设置SSL,否则会返回503错误码。有些解决方案是在Properties中赋值键值对:mail.stmp.socketFactory.class;mail.stmp.socketFactory.port;mail.smtp.socketFactory.fallback; 小Z发现赋值mail.smtp.ssl.enable即可运行代码。
针对不同的的邮件协议,JavaMail规定了服务提供者必须支持一系列属性,下表是针对SMTP协议的一些常见属性(属性值都以String类型进行设置,属性类
型栏仅表示属性是如何被解析的):
属性名 | 属性类型 | 说明 |
mail.stmp.host | String | SMTP服务器地址,如smtp.qq.com |
mail.stmp.port | int | SMTP服务器端口号,默认为25;腾讯使用465 |
mail.stmp.auth | boolean | SMTP服务器是否需要用户认证,默认为false |
mail.stmp.user | String | SMTP默认的登陆用户名 |
mail.stmp.from | String | 默认的邮件发送源地址 |
mail.stmp.socketFactory.class | String | socket工厂类类名,通过设置该属性可以覆盖提供者默认的实现,必须实现javax.net.SocketFactory接口 |
mail.stmp.socketFactory.port | int | 指定socket工厂类所用的端口号,如果没有规定,则使用默认的端口号 |
mail.smtp.socketFactory.fallback | boolean | 设置为true时,当使用指定的socket类创建socket失败后,将使用java.net.Socket创建socket,默认为true |
mail.stmp.timeout | int | I/O连接超时时间,单位为毫秒,默认为永不超时 |
其他几个协议也有类似的一系列属性,如POP3的mail.pop3.host、mail.pop3.port以及IMAP的mail.imap.host、mail.imap.port等。更详细的信息请查看
com.sun.mail.smtp、com.sun.mail.pop3和com.sun.mail.imap这三个包的Javadoc:http://java.sun.com/products/javamail/javadocs/index.html。
授权码认证,小Z另外写了一个类继承Authenticator,重写了方法getPasswordAuthentication,代码如下:
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
public class MailAuthenticator extends Authenticator {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
String username = "sample@qq.com";
String password = "xxx";
return new PasswordAuthentication(username,password);
}
}
最后编写测试客户端,运行sendMail,随后小Z收到了来自自己的问候
代码暂时先到这里吧,如下补充学习了一下相关概念和知识。
JavaMail概述:
JavaMail是由Sun定义的一套收发电子邮件的API,不同的厂商可以提供自己的实现类。但它并没有包含在JDK中,而是作为JavaEE的一部分。
厂商所提供的JavaMail服务程序可以有选择地实现某些邮件协议,常见的邮件协议包括:
SMTP:简单邮件传输协议,用于发送电子邮件的传输协议;
POP3:用于接收电子邮件的标准协议;
IMAP:互联网消息协议,是POP3的替代协议。
这三种协议都有对应SSL加密传输的协议,分别是SMTPS,POP3S和IMAPS。
除JavaMail服务提供程序之外,JavaMail还需要JAF(JavaBeans Activation Framework)来处理不是纯文本的邮件内容,这包括MIME(多用途互联网邮件扩展)、URL页面和文件附件等内容。
mail.jar:此JAR文件包含JavaMail API和Sun提供的SMTP、IMAP和POP3服务提供程序;
activation.jar:此JAR文件包含JAF API和Sun的实现。
对相关协议的回顾:
1、介绍
在研究 JavaMail API 的细则之前,让我们回顾用于 API 的协议。基本上,您会逐渐熟悉并喜爱的协议有四个:
* SMTP
* POP
* IMAP
* MIME
您还将碰到 NNTP 和其它协议。理解所有协议的基本知识将有助于您理解如何使用 JavaMail API。虽然不了解这些协议您照样可以用这个 API,却不能够克服那些基础协议的局限性。如果我们精选的协议不能支持某种性能,JavaMail API 决不能魔术般的将这种性能添加上去。(您很快就会看到,在处理 POP 时这将成为一个难题。)
2、SMTP
简单邮件传输协议(Simple Mail Transfer Protocol,SMTP)由 RFC 821 定义。它定义了发送电子邮件的机制。在 JavaMail API 环境中,您基于 JavaMail 的程序将和您的公司或因特网服务供应商的(Internet Service Provider's,ISP's)SMTP 服务器通信。SMTP 服务器会中转消息给接收方 SMTP 服务器以便最终让用户经由 POP 或 IMAP 获得。这不是要求 SMTP 服务器成为开放的中继,尽管 SMTP 服务器支持身份验证,不过还是得确保它的配置正确。像配置服务器来中继消息或添加删除邮件账号这类任务的实现,JavaMail API 中并不支持。
3、POP
POP 代表邮局协议(Post Office Protocol)。目前用的是版本 3,也称 POP3,RFC 1939 定义了这个协议。POP 是一种机制,因特网上大多数人用它得到邮件。它规定每个用户一个邮箱的支持。这就是它所能做的,而这也造成了许多混淆。使用POP 时,用户熟悉的许多性能并不是由 POP 协议支持的,如查看有几封新邮件消息这一性能。这些性能内建于如 Eudora 或Microsoft Outlook 之类的程序中,它们能记住一些事,诸如最近一次收到的邮件,还能计算出有多少是新的。所以当使用JavaMail API 时,如果您想要这类信息,您就必须自己算。
4、IMAP
IMAP 是更高级的用于接收消息的协议。在 RFC 2060 中被定义,IMAP 代表因特网消息访问协议(Internet Message Access Protocol),目前用的是版本 4,也称 IMAP4。在用到 IMAP 时,邮件服务器必需支持这个协议。不能仅仅把使用 POP 的程序用于 IMAP,并指望它支持 IMAP 所有性能。假设邮件服务器支持 IMAP,基于 JavaMail 的程序可以利用这种情况 — 用户在服务器上有多个文件夹(folder),并且这些文件夹可以被多个用户共享。
因为有这一更高级的性能,您也许会认为所有用户都会使用 IMAP。事实并不是这样。要求服务器接收新消息,在用户请求时发送到用户手中,还要在每个用户的多个文件夹中维护消息。这样虽然能将消息集中备份,但随着用户长期的邮件夹越来越大,到磁盘空间耗尽时,每个用户都会受到损失。使用 POP,就能卸载邮件服务器上保存的消息了。
5、MIME
MIME 代表多用途因特网邮件扩展标准(Multipurpose Internet Mail Extensions)。它不是邮件传输协议。但对传输内容的消息、附件及其它的内容定义了格式。这里有很多不同的有效文档:RFC 822、RFC 2045、RFC 2046 和 RFC 2047。作为一个JavaMail API 的用户,您通常不必对这些格式操心。无论如何,一定存在这些格式而且程序会用到它。
6、NNTP及其他
因为 JavaMail API 将供应商和所有其它的东西分开了,您就能轻松添加额外的协议支持。Sun 保留了一张第三方供应商列表,他们利用了 Sun 不提供超出(out-of-the-box)支持范围的协议。您会找到 NNTP(网络新闻传输协议)[新闻组]、S/MIME(安全多用途因特网邮件扩展)及其它支持。