Mailer

本指南展示 Quarkus 应用程序如何使用 SMTP 服务器发送 email。

必备条件

要完成本指南,您需要:

  • 小于 15 分钟

  • SMTP 主机名、端口和账号密码以及 email 地址

  • IDE

  • 安装了JDK 1.8+ 并正确配置了 JAVA_HOME

  • Apache Maven 3.6.2+

  • 如果您想在 native 模式下运行需要安装好 GraalVM 。

结构

在本指南中,我们将看到如何在 Quarkus 应用程序中发送 email。 它包含简单的email、附件、内嵌附件、反应式和必要的API…​

创建Maven项目

通过以下命令创建一个新项目:

mvn io.quarkus:quarkus-maven-plugin:1.3.1.Final:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=sending-email-quickstart \
    -Dextensions="mailer"
cd sending-email-quickstart

如果您已经有一个现有的项目,请添加 mailer 扩展:

./mvnw quarkus:add-extensions -Dextensions="mailer"

配置 mailer

Quarkus mailer 程序使用 SMTP。 在 src/main/resources/application.properties 文件中,您需要配置主机、 端口、 用户名、 密码以及其他配置项。 请注意,密码也可以使用系统属性和环境变量进行配置。

这是一个使用 _sendgrid_的示例:

quarkus.mailer.from=test@quarkus.io
quarkus.mailer.host=smtp.sendgrid.net
quarkus.mailer.port=465
quarkus.mailer.ssl=true
quarkus.mailer.username=....
quarkus.mailer.password=....
quarkus.mailer.mock=false

建议加密所有敏感数据,例如 quarkus.mailer.password。 一种方法是将该值保存到像 HashiCorp Vault 这样的安全商店,并从配置中引用它。 例如,假定密码库在路径 myapps/myapp/myconfig 中包含密钥 mail-password ,那么 mailer 可以简单地配置为:

...
# path within the kv secret engine where is located the application sensitive configuration
quarkus.vault.secret-config-kv-path=myapps/myapp/myconfig

...
quarkus.mailer.password=${mail-password}

请注意,只在启动时计算一次密码值。 如果在 Vault 中更改了 mail-password , 获取新值的唯一途径是重新启动应用程序。

欲了解更多关于 Mailer extension 配置的信息,请参阅Configuration Reference

发送简单email

在 JAX-RS 资源中,或者在 bean 中,您可以注入 mailer 如下:

@Inject
Mailer mailer;

@Inject
ReactiveMailer reactiveMailer;

有 2 种API:

  • io.quarkus.mailer.Mailer 提供命令式(阻塞和同步) API;

  • io.quarkus.mailer.reactive.ReactiveMailer 提供反应式(非阻塞和异步) API

这两种API 功能上是一样的。 事实上, Mailer 是基于 ReactiveMailer 实现的。
废弃

io.quarkus.mailer.ReactiveMailer 已废弃,用 io.quarkus.mailer.reactive.ReactiveMailer 代替。

Mutiny

反应式 mailer 使用 Mutiny 反应式类型,如果你不熟悉它们,请先参阅 反应式入门指南.

要发送一个简单的电子邮件,请按以下方式进行:

// Imperative API:
mailer.send(Mail.withText("to@acme.org", "A simple email from quarkus", "This is my body."));
// Reactive API:
Uni<Void> stage = reactiveMailer.send(Mail.withText("to@acme.org", "A reactive email from quarkus", "This is my body."));

例如,您可以在 JAX-RS 接口中使用 Mailer 方法如下:

@GET
@Path("/simple")
public Response sendASimpleEmail() {
    mailer.send(Mail.withText("to@acme.org", "A simple email from quarkus", "This is my body"));
    return Response.accepted().build();
}

@GET
@Path("/async")
public CompletionStage<Response> sendASimpleEmailAsync() {
    return reactiveMailer.send(
            Mail.withText("to@acme.org", "A reactive email from quarkus", "This is my body"))
            .subscribeAsCompletionStage()
            .thenApply(x -> Response.accepted().build());
}

使用 quarkus-resteasy-mutiny 扩展,你可以直接返回 Uni 实例。

访问 JAX-RS 接口, 检查下是否工作正常:

curl http://localhost:8080/simple
curl http://localhost:8080/async

你可以从构造函数或用帮助方法 Mail.withTextMail.withHtml 创建新的 io.quarkus.mailer.Mail 实例。 Mail 实例可以让您添加收件人 (to, cc, 或 bcc), 设置主题, headers, 发送者 (from) 地址…​

您也可以在调用一次发送几个 Mail 对象:

mailer.send(mail1, mail2, mail3);

发送附件

若要发送附件,只需使用 io.quarkus.mailer.Mail 实例的 addAttachment 方法:

@GET
@Path("/attachment")
public Response sendEmailWithAttachment() {
    mailer.send(Mail.withText("to@acme.org", "An email from quarkus with attachment",
            "This is my body")
            .addAttachment("my-file.txt",
                "content of my file".getBytes(), "text/plain"));
    return Response.accepted().build();
}

附件可以从原始字节(如代码片段所示) 或从文件创建。

发送包含内嵌 HTML 附件邮件

当发送 HTML 电子邮件时,您可以添加内嵌附件。 例如,您可以通过电子邮件发送一张图片,这张图片将会显示在邮件内容中。 如果你将图像文件放入资源文件夹,你应该指定文件的完整路径。 "例如." "META-INF/resources/quarkus-logo.png" ,否则 Quarkus 会在项目根目录中查找

@GET
@Path("/html")
public Response sendingHTML() {
    String body = "<strong>Hello!</strong>" + "\n" +
        "<p>Here is an image for you: <img src=\"cid:my-image@quarkus.io\"/></p>" +
        "<p>Regards</p>";
    mailer.send(Mail.withHtml("to@acme.org", "An email in HTML", body)
        .addInlineAttachment("quarkus-logo.png",
            new File("quarkus-logo.png"),
            "image/png", "<my-image@quarkus.io>"));
    return Response.accepted().build();
}

注意 content-id 格式和引用。 根据规范,创建内联附件时, content-id 必须结构如下:<id@domain>。 如果你不在 <> 之间包装你的 content-id ,它将自动装上。 当你想引用附件时,例如在 src 属性中,使用 cid:id@domain (没有 <>)。

基于 Qute 模板的邮件内容

也可以注入邮件模板,邮件正文通过 Qute templates 自动创建.

@Inject
MailTemplate hello; (1)

@GET
@Path("/mail")
public CompletionStage<Response> send() {
    return hello.to("to@acme.org") (2)
       .subject("Hello from Qute template")
       // the template looks like: Hello {name}!
       .data("name", "John") (3)
       .send() (4)
       .subscribeAsCompletionStage()
       .thenApply(x -> Response.accepted().build());
}
1 如果没有提供 @ResourcePath 注解,则使用字段名称来定位模板。 本例,我们将使用 hello.htmlhello.txt 模板来创建邮件正文。
2 创建邮件模板实例并设置收件人。
3 设置模板中使用的数据。
4 MailTemplate.send() 触发渲染,并在完成后通过 Mailer 实例发送电子邮件。
注入的邮件模板会在构建时验证。 如果 src/main/resources/templates 中没有匹配的模板,构建失败。

测试邮件发送

因为在开发和测试期间发送电子邮件非常不方便,您可以设置 quarkus.mailer.mocktrue ,这样就不会真的发送电子邮件,而是将它们打印在标准输出上并收集在 MockMailbox 里。 如果您在 DEVTEST 模式运行 Quarkus,默认会这样。

然后您可以写测试用例来验证您的电子邮件是否已经发送,例如通过 REST 接口:

@QuarkusTest
class MailTest {

    private static final String TO = "foo@quarkus.io";

    @Inject
    MockMailbox mailbox;

    @BeforeEach
    void init() {
        mailbox.clear();
    }

    @Test
    void testTextMail() throws MessagingException, IOException {
        // call a REST endpoint that sends email
        given()
        .when()
        .get("/send-email")
        .then()
           .statusCode(202)
           .body(is("OK"));

        // verify that it was sent
        List<Mail> sent = mailbox.getMessagesSentTo(TO);
        assertThat(sent).hasSize(1);
        Mail actual = sent.get(0);
        assertThat(actual.getText()).contains("Wake up!");
        assertThat(actual.getSubject()).isEqualTo("Alarm!");

        assertThat(mailbox.getTotalMessagesSent()).isEqualTo(6);
    }
}

Gmail 特定配置

如果您想使用 Gmail SMTP 服务器, 首先在 Google Account > Security > App passwords 中创建一个专用密码或转至 https://myaccount.google.com/apppasswords

完成后,您可以通过在您的 application.properties 中添加以下属性来配置您的 Quarkus 应用程序:

使用TLS:

quarkus.mailer.auth-methods=DIGEST-MD5 CRAM-SHA256 CRAM-SHA1 CRAM-MD5 PLAIN LOGIN
quarkus.mailer.from=YOUREMAIL@gmail.com
quarkus.mailer.host=smtp.gmail.com
quarkus.mailer.port=587
quarkus.mailer.start-tls=REQUIRED
quarkus.mailer.username=YOUREMAIL@gmail.com
quarkus.mailer.password=YOURGENERATEDAPPLICATIONPASSWORD

或使用 SSL:

quarkus.mailer.auth-methods=DIGEST-MD5 CRAM-SHA256 CRAM-SHA1 CRAM-MD5 PLAIN LOGIN
quarkus.mailer.from=YOUREMAIL@gmail.com
quarkus.mailer.host=smtp.gmail.com
quarkus.mailer.port=465
quarkus.mailer.ssl=true
quarkus.mailer.username=YOUREMAIL@gmail.com
quarkus.mailer.password=YOURGENERATEDAPPLICATIONPASSWORD

Quarkus 邮件程序需要 quarkus.mailer.auth-methods 的配置选项来支持 Gmail的密码认证。 By default both the mailer and Gmail default to XOAUTH2 which requires registering an application, getting tokens, etc.

Native 可执行文件使用 SSL

注意,如果您为 mailer 启用 SSL 并且您想要构建一个 native 可执行程序,您将需要启用 SSL 支持。 欲了解更多信息,请参阅 Native Executables 中使用 SSL 指南 。

使用底层的 Vert.x Vert.x Mail Client

Quarkus Mailer 基于 Vert.x Mail Client 实现,提供异步和非阻塞方式发送 email。 如果您需要细致地控制邮件的发送,例如如果您需要获取 消息ID, 您可以注入底层的 client, 并直接使用它:

@Inject MailClient client;

公开三种类型 API :

  • Mutiny client (io.vertx.mutiny.ext.mail.MailClient)

  • the Axle client (io.vertx.axle.ext.mail.MailClient), using CompletionStage and Reactive Streams Publisher - deprecated, it is recommended to switch to the Mutiny client

  • RX Java 2 client (io.vertx.reactivex.ext.mail.MailClient) - 已废弃,建议切换到 Mutiny 客户端

  • the bare client (io.vertx.ext.mail.MailClient)

查看 使用 Vert.x 指南 以了解关于这些不同 API 以及如何选择最适合您的详细信息。

The retrieved MailClient is configured using the configuration key presented above. 您也可以创建自己的实例并传递自己的配置。

结论

本指南向你展示了如何从 Quarkus 应用程序发送 email。 Extension mailer 在 JVM 和 native 模式都可以使用。

Mailer 配置参考

Configuration property fixed at build time - All other configuration properties are overridable at runtime

Configuration property

Type

Default

Configure the default from attribute. It’s the sender email address.

string

Enables the mock mode, not sending emails. The content of the emails is printed on the console. Disabled by default on PROD, enabled by default on DEV and TEST modes.

boolean

Configures the default bounce email address.

string

The SMTP host name.

string

localhost

The SMTP port.

int

The username.

string

The password.

string

Enables or disables the SSL on connect. false by default.

boolean

false

Set whether to trust all certificates on ssl connect the option is also applied to STARTTLS operation. false by default.

boolean

false

Configures the maximum allowed number of open connections to the mail server If not set the default is 10.

int

The hostname to be used for HELO/EHLO and the Message-ID

string

Set if connection pool is enabled, true by default. If the connection pooling is disabled, the max number of sockets is enforced nevertheless.

boolean

true

Disable ESMTP. false by default. The RFC-1869 states that clients should always attempt EHLO as first command to determine if ESMTP is supported, if this returns an error code, HELO is tried to use the regular SMTP command.

boolean

false

Set the TLS security mode for the connection. Either DISABLED, OPTIONAL or REQUIRED.

string

Set the login mode for the connection. Either DISABLED, OPTIONAL or REQUIRED

string

Set the allowed auth methods. If defined, only these methods will be used, if the server supports them.

string

Set the key store.

string

Set the key store password.

string

quarkus.pro 是基于 quarkus.io 的非官方中文翻译站 ,最后更新 2020/04 。
沪ICP备19006215号-8
QQ交流群:1055930959
微信群: