3.9.2.4. Отправка email
В данном разделе рассматривается пример использования механизма рассылки email.
Рассмотрим следующую задачу:
-
Имеется сущность
NewsItem
и экран ее редактированияNewsItemEdit
. -
Сущность
NewsItem
имеет следующие атрибуты:date
,caption
,content
. -
Необходимо отсылать электронные письма каждый раз, когда через экран
NewsItemEdit
создается новый экземпляр сущности. Email должен содержатьNewsItem.caption
в качестве темы письма, тело письма должно формироваться на основе шаблона, включающегоNewsItem.content
.
-
Добавьте следующий код в
NewsItemEdit.java
:@UiController("sample_NewsItem.edit") @UiDescriptor("news-item-edit.xml") @EditedEntityContainer("newsItemDc") @LoadDataBeforeShow public class NewsItemEdit extends StandardEditor<NewsItem> { private boolean justCreated; (1) @Inject protected EmailService emailService; @Inject protected Dialogs dialogs; @Subscribe public void onInitEntity(InitEntityEvent<NewsItem> event) { (2) justCreated = true; } @Subscribe(target = Target.DATA_CONTEXT) public void onPostCommit(DataContext.PostCommitEvent event) { (3) if (justCreated) { dialogs.createOptionDialog() (4) .withCaption("Email") .withMessage("Send the news item by email?") .withType(Dialogs.MessageType.CONFIRMATION) .withActions( new DialogAction(DialogAction.Type.YES) { @Override public void actionPerform(Component component) { sendByEmail(); } }, new DialogAction(DialogAction.Type.NO) ) .show(); } } private void sendByEmail() { (5) NewsItem newsItem = getEditedEntity(); EmailInfo emailInfo = new EmailInfo( "john.doe@company.com,jane.roe@company.com", (6) newsItem.getCaption(), (7) null, (8) "com/company/demo/templates/news_item.txt", (9) Collections.singletonMap("newsItem", newsItem) (10) ); emailService.sendEmailAsync(emailInfo); } }
1 - флаг, указывающий, что в этом редакторе был создан новый экземпляр сущности NewsItem
.2 - этот метод вызывается при инициализации нового экземпляра сущности. 3 - этот метод вызывается после коммита в data context. 4 - если новый экземпляр был сохранен в базе данных, попросить пользователя об отправке сообщения по электронной почте. 5 - помещает электронное письмо в очередь для асинхронной отправки. 6 - получатели. 7 - тема. 8 - адрес отправителя берется из свойства приложения cuba.email.fromAddress. 9 - путь до шаблона. 10 - параметры шаблона. Как видно, метод
sendByEmail()
вызывает сервисEmailService
и передает ему экземплярEmailInfo
, описывающий сообщение. Тело сообщений будет создаваться на основе шаблонаnews_item.txt
. -
Создайте шаблон тела письма в файле
news_item.txt
в пакетеcom.company.demo.templates
модуля core:The company news: ${newsItem.content}
Это шаблон Freemarker, который использует параметры, переданные в
EmailInfo
(в данном случае единственный параметрnewsItem
). -
Запустите приложение, откройте браузер сущности
NewsItem
и нажмите Create. Откроется экран редактирования сущности. Заполните поля и нажмите OK. Появится диалог подтверждения с вопросом об отсылке email. Нажмите Yes. -
Перейдите в экран Administration > Email History вашего приложения. Вы увидите две записи (по числу получателей) со статусом
Queue
. Он означает, что сообщения находятся в очереди и еще не отосланы. -
Для обработки очереди необходимо создать назначенное задание. Перейдите в экран Administration > Scheduled Tasks вашего приложения. Создайте новую задачу и установите ей следующие параметры:
-
Bean Name -
cuba_Emailer
-
Method Name -
processQueuedEmails()
-
Singleton - да (этот параметр важен только при эксплуатации кластера серверов middleware)
-
Period, sec - 10
Сохраните задачу и нажмите на ней Activate.
Если вы ранее не настраивали выполнение назначенных заданий для данного приложения ранее, то на данном этапе ничего не произойдет - новая задача не начнет выполняться, пока вы не запустите весь механизм назначенных заданий.
-
-
Откройте файл
modules/core/src/app.properties
и добавьте в него следующее свойство:cuba.schedulingActive = true
Перезапустите сервер приложения. Механизм выполнения заданий теперь активен и вызывает обработку очереди email.
-
Перейдите в экран Administration > Email History. Статус сообщений будет либо
Sent
, если они успешно отосланы, либо, что более вероятно,Sending
илиQueue
, если произошла ошибка отправки. В последнем случае вы можете открыть журнал приложения в файлеbuild/tomcat/logs/app.log
и выяснить причину. Механизм отсылки email предпримет несколько (по умолчанию 10) попыток и в случае неудачи переведет сообщения в статусNot sent
. -
Наиболее очевидной причиной ошибки отправки является то, что вы не настроили параметры SMTP-сервера. Эти параметры могут быть заданы в базе данных с помощью JMX бина
app-core.cuba:type=Emailer
или в свойствах приложения блока middleware. Рассмотрим второй способ. Откройте файлmodules/core/src/app.properties
и добавьте в него требуемые параметры:cuba.email.fromAddress = do-not-reply@company.com cuba.email.smtpHost = mail.company.com
Перезапустите сервер приложения. Перейдите в экран Administration > JMX Console, найдите JMX бин
Emailer
и попробуйте послать самому себе тестовое сообщение с помощью операцииsendTestEmail()
. -
Теперь механизм отсылки email настроен корректно, однако он не будет отсылать сообщения, уже переведенные в статус
Not sent
. Поэтому необходимо создать новый экземплярNewsItem
через экран редактирования. Сделайте это и понаблюдайте, как статус новых сообщений в экране Email History изменится наSent
.