<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-mail-client</artifactId>
<version>5.0.1</version>
</dependency>
Vert.x 邮件客户端 (SMTP 客户端实现)
Vert.x 客户端,用于通过本地邮件服务器(例如 postfix)或外部邮件服务器(例如 googlemail 或 aol)发送 SMTP 电子邮件。
该客户端支持一些额外的认证方法,如 DIGEST-MD5,并完全支持 TLS 和 SSL,且是完全异步的。客户端支持连接池,以保持连接开放以供重用。
要使用此项目,请将以下依赖项添加到您的构建描述符的依赖项部分
-
Maven(在您的
pom.xml
中)
-
Gradle(在您的
build.gradle
文件中)
compile 'io.vertx:vertx-mail-client:5.0.1'
创建客户端
您可以通过创建一个客户端来发送邮件,该客户端会从本地 JVM 打开 SMTP 连接。
客户端使用一个配置对象,默认配置被创建为空对象,并将连接到 localhost 的端口 25,这在运行 Postfix 或类似邮件服务器的本地机器上的标准 Linux 环境中应该没问题。有关配置对象的所有可能属性,请参见下文。
客户端可以使用 SMTP 连接的连接池,以避免每次连接到服务器、协商 TLS 和登录的开销(此功能可以通过设置 `keepAlive = false` 来关闭)。客户端可以是共享的或非共享的,如果是共享的,所有使用相同标识符的客户端将使用相同的连接池。
MailConfig config = new MailConfig();
MailClient mailClient = MailClient
.createShared(vertx, config, "exampleclient");
对 `MailClient.createShared` 的首次调用将实际使用指定的配置创建连接池。后续调用将返回一个新的客户端实例,该实例使用相同的连接池,因此配置将不会被使用。
如果您省略连接池标识符,将创建一个默认连接池。请注意,客户端仅在 Vert.x 实例的范围内共享(因此两个不同的 Vert.x 将拥有具有相同标识符的不同连接池)。
非共享客户端可以通过同样的方式创建,省略标识符即可。
MailConfig config = new MailConfig();
MailClient mailClient = MailClient.create(vertx, config);
使用需要通过 TLS 登录的邮件服务器的更详细示例
MailConfig config = new MailConfig();
config.setHostname("mail.example.com");
config.setPort(587);
config.setStarttls(StartTLSOptions.REQUIRED);
config.setUsername("user");
config.setPassword("password");
MailClient mailClient = MailClient.create(vertx, config);
发送邮件
一旦客户端对象创建成功,您就可以使用它来发送邮件。由于邮件发送在 Vert.x 中是异步工作的,因此当邮件操作完成时,结果处理器将被调用。您可以并行启动多个邮件发送操作,连接池将限制并发操作的数量,以便在没有可用插槽时新操作将在队列中等待。
邮件消息以 JSON 形式构建。`MailMessage` 对象具有 `from`、`to`、`cc`、`bcc`、`subject`、`text`、`html` 等属性。根据设置的值,生成的 MIME 消息的格式将有所不同。收件人地址属性可以是单个地址或地址列表。
MIME 编码器支持 us-ascii (7bit) 头部/消息和 utf8 (通常为 quoted-printable) 头部/消息
MailMessage message = new MailMessage();
message.setFrom("[email protected] (Example User)");
message.setTo("[email protected]");
message.setCc("Another User <[email protected]>");
message.setText("this is the plain message text");
message.setHtml("this is html text <a href=\"https://vertx.com.cn\">vertx.io</a>");
附件可以通过 `MailAttachment` 对象使用存储在 `Buffer` 中的数据来创建,这支持 base64 附件。
MailAttachment attachment = MailAttachment.create();
attachment.setContentType("text/plain");
attachment.setData(Buffer.buffer("attachment file"));
message.setAttachment(attachment);
当使用内联附件(通常是图片)时,可以在 HTML 消息中引用图片,以便在邮件中显示包含图片的 HTML。图片可以在 HTML 文本中引用为 ``,相应的图片具有 `Disposition: inline` 和 `Content-ID` 头部,格式为 `"
MailAttachment attachment = MailAttachment.create();
attachment.setContentType("image/jpeg");
attachment.setData(Buffer.buffer("image data"));
attachment.setDisposition("inline");
attachment.setContentId("<[email protected]>");
message.setInlineAttachment(attachment);
发送邮件时,您可以提供一个 `AsyncResult
邮件发送方式如下
mailClient.sendMail(message)
.onSuccess(System.out::println)
.onFailure(Throwable::printStackTrace);
DKIM 签名邮件
它支持 DomainKeys Identified Mail (DKIM) 签名以保护您的电子邮件。您只需指定所需的配置即可为您的电子邮件签名。
启用 DKIM 功能的邮件客户端可以按如下方式创建
DKIMSignOptions dkimSignOptions = new DKIMSignOptions();
dkimSignOptions.setPrivateKey("PKCS8 Private Key Base64 String");
dkimSignOptions.setAuid("[email protected]");
dkimSignOptions.setSelector("selector");
dkimSignOptions.setSdid("example.com");
MailConfig config = new MailConfig()
.setDKIMSignOption(dkimSignOptions)
.setEnableDKIM(true);
MailClient mailClient = MailClient.createShared(vertx, config);
邮件客户端创建后,每次 mailClient.sendMail
调用都会通过添加额外的 DKIM-Signature
头部来为电子邮件签名。
缓存 DKIM 中使用的附件流
为了执行 DKIM 签名,需要对电子邮件正文(包括附件)进行哈希。如果附件来自 `ReadStream`,它将无法再次读取。因此我们需要缓存附件数据。该客户端提供了两种缓存策略。
-
内存缓存
默认情况下,流内容会缓存在内存中,以便稍后发送。
-
缓存到临时文件
您可以通过指定系统属性 vertx.mail.attachment.cache.file
为 true
来将附件流中的数据缓存到临时文件中,适用于大型附件。每次发送后,它会尝试删除临时文件。
邮件客户端数据对象
`MailMessage` 属性
电子邮件字段是字符串,使用电子邮件的常见格式,带或不带真实姓名
-
[email protected] (名字 姓氏)
-
名字 姓氏 <[email protected]>
`MailMessage` 对象具有以下属性
-
from
表示发件人地址和 `MAIL FROM` 字段的字符串 -
to
表示收件人地址和 `RCPT TO` 字段的字符串或字符串列表 -
cc
同 `to` -
bcc
同 `to` -
bounceAddress
表示错误地址 (`MAIL FROM`) 的字符串,如果未设置则使用 `from` -
text
表示邮件 `text/plain` 部分的字符串 -
html
表示邮件 `text/html` 部分的字符串 -
attachment
邮件附件 (`MailAttachment`) 或消息附件列表 (`MailAttachment` 列表) -
inlineAttachment
邮件内联附件 (`MailAttachment`) 或消息内联附件列表 (`MailAttachment` 列表) (通常是图片) -
headers
表示除了 MIME 消息所需的头部之外要添加的头部的 `MultiMap` -
fixedHeaders
布尔值,如果为 `true`,则生成的邮件中将只设置作为 `headers` 属性提供的头部
最后两个属性允许使用自定义头部操作生成的消息,例如提供由调用程序选择的 message-id 或设置与默认生成不同的头部。除非您知道自己在做什么,否则这可能会生成无效消息。
MailAttachment 属性
`MailAttachment` 对象具有以下属性
-
data
包含附件二进制数据的 `Buffer` -
stream
表示附件二进制数据源的 `ReadStream` -
size
整数,描述当使用 `stream` 作为二进制数据源时附件的大小 -
contentType
附件的 `Content-Type` 字符串(例如 `text/plain` 或 `text/plain; charset="UTF8"`,默认值为 `application/octet-stream`) -
description
描述附件的字符串(此内容放置在附件的 description 头部中),可选 -
disposition
描述附件处置方式的字符串(可以是 "inline" 或 "attachment",默认是 `attachment`) -
name
附件的文件名字符串(此内容放置在附件的 disposition 和 `Content-Type` 头部中),可选 -
contentId
描述附件 `Content-Id` 的字符串(用于识别内联图片),可选 -
headers
除了默认头部之外的附件头部 `MultiMap`,可选
MailConfig 选项
配置具有以下属性
-
hostname
要连接的 SMTP 服务器主机名(默认是 localhost) -
port
要连接的 SMTP 服务器端口(默认是 25) -
startTLS
`StartTLSOptions`,可以是 `DISABLED`、`OPTIONAL` 或 `REQUIRED`,默认是 `OPTIONAL` -
login
`LoginOption`,可以是 `DISABLED`、`NONE` 或 `REQUIRED`,默认是 `NONE` -
username
用于登录的用户名字符串(仅当 `LoginOption` 为 `REQUIRED` 时需要) -
password
用于登录的密码字符串(仅当 `LoginOption` 为 `REQUIRED` 时需要) -
ssl
布尔值,表示连接到邮件服务器时是否使用 SSL(默认是 `false`),设置为 `true` 可使用 465 端口的 SSL 连接(默认是 `false`) -
ehloHostname
用于 EHLO 和创建 message-id 的字符串,如果未设置,则使用自己的主机名,如果它不包含 FQDN 或为 localhost,则可能不是一个好的选择(可选) -
authMethods
允许的认证方法的字符串,以空格分隔的列表,可用于禁止某些认证方法或定义一个必需的认证方法(可选) -
keepAlive
布尔值,如果连接池已启用(默认是 `true`) -
maxPoolSize
整数,连接池中保持的最大开放连接数或一次性打开的最大连接数(无论是否启用连接池),默认是 10 -
trustAll
布尔值,是否接受服务器的所有证书(默认是 `false`) -
keyStore
密钥库文件名字符串,可用于信任自定义生成的服务器证书(可选) -
keyStorePassword
用于解密密钥库的密码字符串(可选) -
allowRcptErrors
布尔值,如果为 `true`,则当收件人地址不被接受时发送会继续,并且如果至少一个地址被接受,邮件仍将发送(默认是 `false`) -
disableEsmtp
布尔值,如果为 `true`,将不使用 ESMTP 相关命令(如果您的 SMTP 服务器甚至不为 EHLO 命令提供正确的错误响应代码,则设置此项)(默认是 `false`) -
userAgent
字符串,表示用于生成多部分电子邮件边界和 message-id 的邮件用户代理 (MUA) 名称,默认是vertxmail
。 -
enableDKIM
布尔值,如果为 `true`,则当也设置了 DKIM 配置时,DKIM 签名将被启用,默认是 `false`。 -
dkimSignOptions
`DKIMSignOptions` 列表,用于执行 DKIM 签名。 -
pipelining
如果 SMTP 服务器支持,则启用管道化。默认是true
-
multiPartOnly
布尔值,是否仅将邮件消息编码为多部分。默认是false
-
poolCleanerPeriod
整数,连接池清理器周期(毫秒)。默认是1000 ms
。 -
poolCleanerPeriodUnit
清理连接池的时间单位,默认是TimeUnit.MILLISECONDS
-
keepAliveTimeout
整数,SMTP 连接的保持活动超时时间(秒)。默认是300 s
。 -
keepAliveTimeoutUnit
保持连接池中连接活动的时间单位。默认是TimeUnit.SECONDS
-
ntDomain
字符串,用于 NTLM 认证的域名。如果username
遵循<DOMAIN>\<UserName>
格式,则\
之前的部分将用作域名。 -
workstation
字符串,用于 NTLM 认证的工作站名称 -
maxMailsPerConnection
长整数,每个连接在关闭前可发送的最大邮件数量
MailResult 对象
`MailResult` 对象具有以下成员
-
messageID
生成邮件的 `Message-ID` -
recipients
邮件发送到的收件人列表(如果 `allowRcptErrors` 为 `true`,此列表可能少于预期的收件人)
DKIMSignOptions 对象
`DKIMSignOptions` 对象具有以下属性
-
privateKey
用于签署电子邮件的 RSA PKCS#8 格式私钥。 -
privateKeyPath
指定 RSA PKCS#8 格式私钥的文件路径。privateKey
或privateKeyPath
必须设置其中之一。 -
signAlgo
`DKIMSignAlgorithm.RSA_SHA256`(默认)或 `DKIMSignAlgorithm.RSA_SHA1`。用于正文哈希和签名算法。 -
signedHeaders
字符串列表,指定将用于执行签名的电子邮件头部。默认值:From
、Reply-to
、Subject
、Date
、To
、Cc
。注意:顺序很重要。 -
sdid
必需,字符串,签名域标识符 (SDID),通常是 SMTP 服务器的域。 -
auid
可选,字符串,代理或用户标识符 (AUID),默认是 `@` 加sdid
-
selector
必需,字符串,用于查询公钥的选择器。 -
headerCanonAlgo
用于邮件头部的规范化算法,可以是simple
(默认)或relaxed
。 -
bodyCanonAlgo
用于邮件正文的规范化算法,可以是simple
(默认)或relaxed
。 -
bodyLimit
可选,整数,用于计算正文哈希的正文长度。 -
signatureTimestamp
可选,布尔值,是否在DKIM-Signature
标签列表中包含时间戳。默认是 `false` -
expireTime
可选,长整数,从现在起签名将过期的时间(秒)。 -
copiedHeaders
可选,字符串列表,DKIM 中使用的复制头部。通常根据 DKIM 规范用于调试目的。