5.8.7. Отправка email
В данном разделе рассматривается пример использования механизма рассылки email.
Рассмотрим следующую задачу:
-
Имеется сущность
NewsItem
и экран ее редактированияNewsItemEdit
. -
Сущность
NewsItem
имеет следующие атрибуты:date
,caption
,content
. -
Необходимо отсылать электронные письма каждый раз, когда через экран
NewsItemEdit
создается новый экземпляр сущности. Email должен содержатьNewsItem.caption
в качестве темы письма, тело письма должно формироваться на основе шаблона, включающегоNewsItem.content
.
-
Добавьте следующий код в
NewsItemEdit.java
:public class NewsItemEdit extends AbstractEditor<NewsItem> { // Indicates that a new item was created in this editor private boolean justCreated; @Inject protected EmailService emailService; // This method is invoked when a new item is initialized @Override protected void initNewItem(NewsItem item) { justCreated = true; } // This method is invoked after the screen commit @Override protected boolean postCommit(boolean committed, boolean close) { if (committed && justCreated) { // If a new entity was saved to the database, ask a user about sending an email showOptionDialog( "Email", "Send the news item by email?", MessageType.CONFIRMATION, new Action[] { new DialogAction(DialogAction.Type.YES) { @Override public void actionPerform(Component component) { sendByEmail(); } }, new DialogAction(DialogAction.Type.NO) } ); } return super.postCommit(committed, close); } // Queues an email for sending asynchronously private void sendByEmail() { NewsItem newsItem = getItem(); EmailInfo emailInfo = new EmailInfo( "john.doe@company.com,jane.roe@company.com", // recipients newsItem.getCaption(), // subject null, // the "from" address will be taken from the "cuba.email.fromAddress" app property "com/company/demo/templates/news_item.txt", // body template Collections.singletonMap("newsItem", newsItem) // template parameters ); emailService.sendEmailAsync(emailInfo); } }
Как видно, метод
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
.