开始使用

本章节是发送电子邮件的实用指南。

假设在每次通过实体浏览界面创建新实体实例时,我们都需要向某些地址发送电子邮件。

首先,按照 安装 部分的说明进行安装。

创建实体和界面

  1. 创建 NewsItem 实体,包含下列属性:

    • date,为 LocalDate 类型。

    • caption,为 String 类型。

    • content,为 String 类型,长度无限制。

  2. 创建 NewsItemBrowseNewsItemEdit 界面。

添加确认对话框

首先,我们检查是否打开了实体编辑界面用于创建新实体。

为编辑界面添加布尔类型的 justCreated 属性,并订阅 InitEntity 事件。

private boolean justCreated;

@Subscribe
public void onInitEntity(InitEntityEvent<NewsItem> event) {
    justCreated = true;
}

当每次为新实体打开编辑界面时,将 justCreated 设置为 true

然后,订阅 PostCommit 事件并添加下列代码:

private static final Logger log = LoggerFactory.getLogger(NewsItemEdit.class);

@Inject
protected Dialogs dialogs;

@Subscribe(target = Target.DATA_CONTEXT)
public void onPostCommit(DataContext.PostCommitEvent event) {
    if (justCreated) { (1)
        dialogs.createOptionDialog() (2)
                .withCaption("Email")
                .withMessage("Send the news item by email?")
                .withActions(
                        new DialogAction(DialogAction.Type.YES) {
                            @Override
                            public void actionPerform(Component component) {
                                try {
                                    sendByEmail(); (3)
                                } catch (IOException e) {
                                    log.error("Error sending email", e);
                                }
                            }
                        },
                        new DialogAction(DialogAction.Type.NO)
                )
                .show();
    }
}
1 此方法在数据上下文提交之后调用。
2 如果新实体保存至数据库,询问用户是否发送邮件。
3 调用发送邮件的方法。

添加发送邮件方法

我们添加 postCommit 中调用的 sendbyEmail 方法,异步发送邮件。为了演示如何添加附件,我们给邮件添加一个公司的 logo 图片:

@Autowired
private Emailer emailer;

@Autowired
protected Resources resources;

private void sendByEmail() throws IOException {
    InputStream resourceAsStream = resources.getResourceAsStream("email/ex1/logo.png");
    byte[] bytes = IOUtils.toByteArray(resourceAsStream); (1)
    EmailAttachment emailAtt = new EmailAttachment(bytes,
            "logo.png", "logoId"); (2)
    NewsItem newsItem = getEditedEntity();
    EmailInfo emailInfo = EmailInfoBuilder.create()
            .setAddresses("john.doe@company.com,jane.doe@company.com") (3)
            .setSubject(newsItem.getCaption()) (4)
            .setFrom(null) (5)
            .setBody(newsItem.getContent())
            .setAttachments(emailAtt) (6)
            .build();
    emailer.sendEmailAsync(emailInfo);
}
1 将文件转换为字节数组。
2 创建 EmailAttachment 对象。
3 收件人。
4 邮件主题。
5 发送人地址从 jmix.email.from-address 应用程序属性获取。
6 设置附件。

设置发送参数

SMTP 服务器的 参数 可以在应用程序中的 application.properties 文件中配置:

spring.mail.host = mail.company.com
jmix.email.from-address = info@company.com

下面是连接至 Google SMTP 服务的配置:

spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.protocol=smtp
spring.mail.username=username
spring.mail.password=password
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true

使用 UI

启动应用程序,打开 NewsItem 实体浏览界面,然后点击 Create(新建)。在编辑界面填写完实体信息后,点击 OK。此时会弹出窗口询问是否发送电子邮件,选择 Yes

confirmation

切换至应用程序的 Administration(管理) → Email History(邮件历史) 界面。此时可以看到一行状态为 Queue(排队中) 的记录。表示邮件仍然在排队,并未发送。邮件信息展示在右侧。

如需周期性地发送排队的邮件,可以配置 Quartz 调度器

如需从界面发送邮件,在 Administration(管理) → Email History(邮件历史) 中选择需要发送的邮件,然后点击 Resend email(再次发送)。可以在发送之前修改或添加收件人。发送成功后,表格中的状态会变成 Sent(已发送)

resend