Поиск по этому блогу

понедельник, 1 июля 2013 г.

GAE MailService

Задача отправки писем на email зарегистрированным пользователем из приложения, которое работает на Google App Engine (GAE). Для реализации этой задачи нам понадобиться использовать следующие средства:

  • Шаблонизатор Freemaker для создания шаблона письма
  • QueueFactory для получения очереди задач и добавления в эту очередь задачи отправки письма
  • DeferredTask интерфейс будет реализовывать класс задачи которая будет отпарлять пиьсмо, для того чтобы мы могли добавить эту задачи в очередь
  • GAE MailService для создания и отправки письма


Шаблонизатор Freemaker


Почитать о том, что такое шаблонизатор freemaker можно здесь:

http://freemarker.sourceforge.net/
http://ru.wikipedia.org/wiki/FreeMarker
http://freemarker.org/docs/

Maven-зависимость можно взять здесь

http://mvnrepository.com/artifact/org.freemarker/freemarker

Для подключения зависимости в файле pom.xml добавляем следующие строки

<dependency>
  <groupId>org.freemarker</groupId>
  <artifactId>freemarker-gae</artifactId>
  <version>2.3.19</version>
</dependency>

Кратко говоря, мы создаем шаблон письма, который потом заполняем из Java-кода нужными нам данными.

HTML-шаблон 


Сам файл шаблона письма должен располагаться по следующему адресу:
src/main/resources/notificationEmail.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>[Заголовок письма]</title>
</head>
<body>
 
  <p>Здравствуйте, ${userName}!</p>
  <p>${message}</p>
  <img alt="Картинка" src="http://[адрес вашего сайта]/img/img.png">
  <p>Сайт сервиса "Имя Сервиса" - тут слоган сервиса</p> 
  <p>http://[адрес вашего сайта]/</p>
 
</body>
</html>

Тут переменные ${userName} и ${message} будут принимать значения, которые будут переданы из Java-кода. 

Метод,  добавляющий в очередь задач задачу отправки email-сообщения 


private void sendNotificationToCargoOwnerEmail(User user, Cargo cargo,
  Truck truck, Date date) {
 
    Queue queue = QueueFactory.getDefaultQueue();
    queue.add(TaskOptions.Builder
     .withRetryOptions(RetryOptions.Builder
     .withTaskRetryLimit(3)).payload(
     new SendNotificationToCargoOwnerEmailTask(
       "Здесь пишем заголовок сообщения",user,
       "Здесь пишем текст сообщения")));
}

Класс задачи, которая будет отправлять письма


Создаем объект ClassLoader для загрузки файла шаблона. После этого создаем шаблон на основе загруженного файла-шаблона.

ClassLoader classLoader = Thread.currentThread()
  .getContextClassLoader();
 
Template template = new Template("notificationEmail.html",
  new InputStreamReader(classLoader
  .getResourceAsStream("notificationEmail.html"),
  "UTF-8"), new Configuration(), "UTF-8");

Создаем HashMap, в которую добавляем две пары ключ-значение. Ключи userName и message соответствуют переменным из html-шаблона

Map<String, Object> rootMap = new HashMap<String, Object>();
rootMap.put("userName", user.getFullName());
rootMap.put("message", message);

Создаем объект класса StringWriter, в который запишем информацию из HashMap

StringWriter stringWriter = new StringWriter();

Информацию из HashMap записываем в stringWriter.

template.process(rootMap, stringWriter);

Получаем объект mailService, создаем сообщение message, устанавливаем сообщению отправителя, заголовок, получателя. Также задаем текст сообщения, путем преобразования объекта stringWriter в строку. Теперь наконец отправляем сообщение.

MailService mailService = MailServiceFactory.getMailService();
Message message = new Message();
message.setSender("noreply@ipoint.ru");
message.setSubject(title);
message.setTo(user.getUserEmail());
message.setHtmlBody(stringWriter.toString());
mailService.send(message);

Класс задачи полностью


package com.ipoint.trucking.web.server.tasks.email;
 
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
 
import com.google.appengine.api.mail.MailService;
import com.google.appengine.api.mail.MailService.Message;
import com.google.appengine.api.mail.MailServiceFactory;
import com.google.appengine.api.taskqueue.DeferredTask;
import com.ipoint.trucking.web.domain.User;
 
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
 
public class SendNotificationToCargoOwnerEmailTask implements DeferredTask {
 
  private String title;
 
  private String message;
 
  private User user;
 
  public SendNotificationToCargoOwnerEmailTask(String title, User user, 
    String message) {
      this.title = title;
      this.message = message;
      this.user = user;
  }
 
  @Override
  public void run() {
 
    try {
 
      ClassLoader classLoader = Thread.currentThread()
        .getContextClassLoader();
 
      Template template = new Template("notificationEmail.html",
        new InputStreamReader(classLoader
        .getResourceAsStream("notificationEmail.html"),
 "UTF-8"), new Configuration(), "UTF-8");
 
      StringWriter stringWriter = new StringWriter();
      Map<String, Object> rootMap = new HashMap<String, Object>();
      rootMap.put("userName", user.getFullName());
      rootMap.put("message", message);   
 
      MailService mailService = MailServiceFactory.getMailService();
      Message message = new Message();
      message.setSender("noreply@ipoint.ru");
      message.setSubject(title);
      message.setTo(user.getUserEmail());
      template.process(rootMap, stringWriter);
      message.setHtmlBody(stringWriter.toString());
      mailService.send(message);
 
    } catch (IOException e) {
      log.log(Level.WARNING, e.getMessage(), e);
    } catch (TemplateException e) {
      log.log(Level.WARNING, e.getMessage(), e);
    }
 
  }
}

Комментариев нет:

Отправить комментарий