使用 Java 和 Yahoo! Mail 发送电子邮件
Javax Mail 库的简短教程。
引言
有时候,程序能够向订阅者发送电子邮件通知会非常有帮助。我相信我们都这样做过。使用 .NET,可以通过 Outlook SMTP 服务器轻松创建此类功能。本教程将向您展示这样做也很容易。此外,我还想向您展示如何通过 SMTP 连接到 Yahoo! Mail 帐户并向同一帐户发送电子邮件。如果您可以从同一帐户发送电子邮件到同一帐户,那么您就可以将其用于发送到任何地址。
在学会如何从您的 Yahoo! Mail 帐户发送电子邮件后,请不要用它来垃圾邮件骚扰他人。特别是不要一次性大量发送垃圾邮件。如果您这样做,我相信您会惹上麻烦。您的 Yahoo! Mail 可能会被暂停、强制删除,或可能导致其他严重后果。请注意。
无论如何,相同的功能也可以用于 Google Mail 帐户。事实上,在我将硬编码的帐户信息更改为 Yahoo! Mail 帐户之前,它就可以在 Google Mail 帐户上正常工作。我这样做是因为安全原因。对于 Google 帐户,我必须转到安全配置页面,开启允许第三方应用程序访问我的 Google Mail 帐户的设置。这只是一个可以开关的简单切换。对我来说,这不够安全。
另一方面,Yahoo! Mail 使用一种更安全的方式来允许我的应用程序访问我自己的邮件帐户。注册新帐户后,我必须在手机上下载 Yahoo! 的邮件应用程序,并启用两步验证。然后,我才能进入安全配置,启用我的邮件以允许第三方应用程序访问。这里有一个转折,不是一个开关,我可以打开/关闭邮件访问,而是我必须为第三方应用程序创建一个单独的密码。这与 Google Mail 不同,这意味着我的主密码不需要暴露。有了这样的区别,我觉得 Yahoo! Mail 在处理我的帐户访问方面更好。缺点是 Yahoo! Mail 充斥着广告。唯一的删除广告的方法是升级到付费版本。我不太关心广告,只使用该帐户处理非必需的通知。
在下一节中,我将详细向您展示如何配置 Yahoo! Mail 帐户以启用第三方访问。
启用 Yahoo! Mail 的第三方应用程序访问
我最初处理这个问题时,以为很简单,连接到 SMTP 服务器只需要使用我的用户名和主密码。当我连接时收到拒绝访问的提示,我感到很惊讶。反复出现的错误是用户名和密码不匹配。经过深入研究,我才意识到我需要为我的帐户明确授权第三方应用程序访问。以下是您可以启用此类授权的步骤。
如果您还没有注册 Yahoo! Mail 帐户,您可以使用用户名、一个好的安全密码、您的出生日期以及可选的性别进行注册。注册后,您可以提供手机号码以及另一个电子邮件地址用于密码恢复。最好之后安装 Yahoo! Mail 应用程序并启用推送身份验证。如果您不这样做,将无法授权第三方应用程序访问您的 Yahoo! Mail 帐户。
首先,您可以使用用户名登录,然后点击“下一步”。
如果您没有在手机上登录您的 Yahoo! Mail 应用程序,您可以使用您的主密码登录。如果您有 Yahoo! Mail,那么您会看到您的邮件帐户主页。就像这样
转到页面右上角,您会找到您的用户名。这是一个可点击的字段。
点击它,您会看到一个下拉菜单,就像这样
在下拉菜单中,有一个链接叫做“帐户信息”。点击以访问它。
点击后,系统会要求您再次登录以查看“帐户安全”页面。登录后,您会看到以下页面
在最底部,您会看到“管理应用程序密码”。点击它。
从这个屏幕截图中可以看到,弹出的窗口显示了可以访问此 Yahoo! 邮件帐户的应用程序列表。我已经添加了一个,如列表所示。点击“选择您的应用程序”弹出下拉菜单,就像这样
在下拉列表的最底部,找到“其他应用程序”选项。选择它。下拉菜单变成一个文本框,您可以在其中输入一个名称。就像这样
输入一个有意义的名称,然后点击“生成”。这将生成一个密码并与一个名称关联。就像这样
一旦获得密码,您必须将其写在以后可以访问的地方,因为如果您点击“完成”,您将再也看不到这个密码。不要丢失它。
一旦您保存了密码,点击“完成”,您就设置好了。
本教程最重要的部分已经完成。接下来,我们将介绍项目代码。
使用 Yahoo! Mail 发送电子邮件的 Java 项目
本教程我希望保持简单。该项目包含一个 public
类。里面有一个主入口方法。连接到 SMTP、创建电子邮件内容以及发送的整个过程都可以在此方法中找到。我从 Maven POM 文件开始。我用它来创建 Eclipse 项目。最后,我将项目导入 Eclipse。在 Eclipse 中,我编写代码并在其中运行。关键是,一旦您知道如何一次性完成所有操作,就可以将其重构为实用工具类并集成到您的项目中。
POM XML 文件
Maven POM 文件可以在关联的源文件部分找到。我不想在这份文件的内容上花费太多时间。我唯一想讨论的是此项目所需的依赖项——Javax Mail 库。
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
这是您唯一需要的依赖项。它会强制下载更多依赖项。令人困惑的是,还有一个依赖项,其 artifact-id
是 javax.mail-api
。如果您尝试使用这个错误的依赖项运行此程序,您将收到一个运行时异常。这个库 javax.mail-api
只有 Javax Mail 的接口,没有实现,这就是为什么程序无法工作。
接下来,我们将查看源代码。
Java 源代码
此程序的 Java 源代码很简单。这是整个程序
package org.hanbo.yahoo.mail.sample;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
public class App
{
public static void main(String[] args)
{
final String to = "nobunagX.XXXXXXX@yahoo.com";
final String from = "nobunagX.XXXXXXX@yahoo.com";
String host = "smtp.mail.yahoo.com";
Properties properties = System.getProperties();
properties.put("mail.smtp.host", host);
properties.put("mail.smtp.port", "587");
properties.put("mail.smtp.starttls.enable", "true");
properties.put("mail.smtp.auth", "true");
Session session = Session.getInstance(properties, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("nobunagX.XXXXXXX", "XXXXgdflXXXXinta");
}
});
session.setDebug(true);
try {
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
message.setSubject("This is the Subject Line!");
message.setText("This is actual message");
System.out.println("sending...");
Transport.send(message);
System.out.println("Sent message successfully....");
} catch (MessagingException mex) {
mex.printStackTrace();
}
}
}
让我们逐行看一下。首先,我声明了两个局部变量,它们代表要发送电子邮件的 发件人
和 收件人
地址。
final String to = "nobunagX.XXXXXXX@yahoo.com";
final String from = "nobunagX.XXXXXXX@yahoo.com";
这两个地址是相同的,因为我想从自己发送电子邮件到自己,而不是骚扰别人。接下来,我将创建一个属性集合来存放一些键值对。它们是 Yahoo! Mail 服务器信息的引用。
String host = "smtp.mail.yahoo.com";
Properties properties = System.getProperties();
properties.put("mail.smtp.host", host);
properties.put("mail.smtp.port", "587");
properties.put("mail.smtp.starttls.enable", "true");
properties.put("mail.smtp.auth", "true");
这里有几点需要注意。
- 邮件主机是
smtp.mail.yahoo.com
。 - 端口号是
587
。还有一个端口号,是用于旧版 SSL 连接的。您不应该使用它。下一端口是原因。 mail.smtp.starttls.enable
设置为true
。我相信此选项启用了 TLS 进行数据传输。这比 SSL 传输更安全。因此,您应该使用此选项以及端口号587
,而不是 SSL 和不同的端口号。SSL 最终会被弃用。- 最后一个指定了身份验证以建立连接。
下一步是创建一个邮件会话对象。当我声明 session
对象时,我还指定了 Yahoo! Mail 服务器的用户名和密码。这里我输入的是我的用户名,不带“@yahoo.com
”后缀,密码是我在帐户信息页面生成的密码。这不是我注册邮件服务时的主密码。
Session session = Session.getInstance(properties, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("nobunagX.XXXXXXX", "XXXXgdflXXXXinta");
}
});
session.setDebug(true);
运行测试时,您需要将用户名和密码替换为您自己的用户名和密码。
在会话对象上开启调试模式可以更轻松地进行故障排除。在操作上,它的作用不大。
这是创建邮件消息的代码,它需要 session
对象。这与 .NET 邮件 API 的工作方式不同。我猜当邮件发送时,session
会被创建。一旦邮件到达服务器,session
就会关闭。
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
message.setSubject("This is the Subject Line!");
message.setText("This is actual message");
最后,以下代码将发送消息。
System.out.println("sending...");
Transport.send(message);
System.out.println("Sent message successfully....");
这就是使用 Yahoo! Mail 服务发送电子邮件所需的所有内容。
如何测试
要构建应用程序,请运行以下命令:
mvn clean install
要创建 Eclipse 项目,请运行以下命令:
mvn eclipse:eclipse
如果可以导入项目到 Eclipse,您可以展开项目,找到 Java 文件所在的位置。选中它,右键单击,然后选择“运行方式”->“Java 应用程序”。
要使用 Maven 运行此程序,请使用以下命令:
mvn exec:java -Dexec.mainClass="org.hanbo.yahoo.mail.sample.App"
只要构建成功,您应该就可以运行程序了。以下是显示电子邮件已成功发送的扩展输出日志。
DEBUG: setDebug: JavaMail version 1.6.2
sending...
DEBUG: getProvider() returning javax.mail.Provider
[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
DEBUG SMTP: need username and password for authentication
DEBUG SMTP: protocolConnect returning false, host=smtp.mail.yahoo.com,
user={{XXXXXXX}}, password=<null>
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "smtp.mail.yahoo.com", port 587, isSSL false
220 smtp.mail.yahoo.com ESMTP ready
DEBUG SMTP: connected to host "smtp.mail.yahoo.com", port: 587
EHLO XXXXXXXXXXXX
250-smtp429.mail.gq1.yahoo.com Hello {{XXXXXXXXXXXX}} [xxx.xxx.xxx.xxx])
250-PIPELINING
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-SIZE 41697280
250 STARTTLS
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "SIZE", arg "41697280"
DEBUG SMTP: Found extension "STARTTLS", arg ""
STARTTLS
220 2.0.0 Ready to start TLS
EHLO XXXXXXXXXXXX
250-smtp429.mail.gq1.yahoo.com Hello XXXXXXXXXXXX [xxx.xxx.xxx.xxx])
250-PIPELINING
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-SIZE 41697280
250 AUTH PLAIN LOGIN XOAUTH2 OAUTHBEARER
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "SIZE", arg "41697280"
DEBUG SMTP: Found extension "AUTH", arg "PLAIN LOGIN XOAUTH2 OAUTHBEARER"
DEBUG SMTP: protocolConnect login, host=smtp.mail.yahoo.com,
user=nobunagX.XXXXXXX, password=<non-null>
DEBUG SMTP: Attempt to authenticate using mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM XOAUTH2
DEBUG SMTP: Using mechanism LOGIN
DEBUG SMTP: AUTH LOGIN command trace suppressed
DEBUG SMTP: AUTH LOGIN succeeded
DEBUG SMTP: use8bit false
MAIL FROM:<nobunagX.XXXXXXX@yahoo.com>
250 2.1.0 Sender <nobunagX.XXXXXXX@yahoo.com> OK
RCPT TO:<nobunagX.XXXXXXX@yahoo.com>
250 2.1.5 Recipient <nobunagX.XXXXXXX@yahoo.com> OK
DEBUG SMTP: Verified Addresses
DEBUG SMTP: nobunagX.XXXXXXX@yahoo.com
DATA
354 Ok Send data ending with <CRLF>.<CRLF>
Date: Tue, 21 Apr 2020 23:28:50 -0400 (EDT)
From: nobunagX.XXXXXXX@yahoo.com
To: nobunagX.XXXXXXX@yahoo.com
Message-ID: <1880587981.0.1587526130394@XXXXXXXXXXXX>
Subject: This is the Subject Line!
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
This is actual message
.
250 OK , completed
DEBUG SMTP: message successfully delivered to mail server
QUIT
221 Service Closing transmission
Sent message successfully....
检查 Yahoo! Mail 收件箱,您应该会看到类似这样的内容:
摘要
这是一个关于 Javax Mail 库的简短教程。如您所见,Javax Mail 库是一个非常易于使用的库。当我刚开始进行这项工作并成功完成后,我认为整个设置非常酷,值得记录。因此,就有了这个教程。困难的部分是弄清楚 Yahoo! Mail 的安全配置。
这个教程虽然内容不多,但在很多场景下都很有用。例如,您可以为您的博客设置一个通知服务。每当您的帖子有评论时,它就可以发送一封电子邮件通知您。或者您可以设置一个监控股票的人工智能服务,当股票达到一个好的价格时,该服务就可以给您发送电子邮件。还有很多其他场景也适合使用这样的功能。本教程让您可以轻松创建这样的功能。希望您觉得有用。
感谢您的访问...
历史
- 2020 年 4 月 21 日 - 初稿