Присвоение имен JNDI в Apache Geronimo и пулы подключений ресурсов Java, Часть 3: Почтовые сессии

Использование Geronimo и JNDI для создания, доступа и подтверждения получения электронной почты

До сих пор в данном цикле вы создали соединение источников данных и группу ресурсов Java-сервиса обмена сообщениями (JMS) и выяснили, как каждый из них работает с Apache Geronimo и Java™ Naming and Directory Interface (JNDI). В данной статье, третьей в цикле из четырех статей, описано, как взаимосвязаны Apache Geronimo, JNDI и почтовые сессии. Вы узнаете, как создать почтовую сессию и обратиться к ней в простом приложении Geronimo, используя JNDI.

Дэйл де лос Рейес, автор, внештатный писатель

Дэйл де лос Рейес (Dale de los Reyes) закончил в 1996 году Калифорнийский Политехнический Государственный Университет с дипломом специалиста по вычислительной технике. Его опыт работы включает разработку приложений на J2EE, C++ для Microsoft® Windows® и COBOL для центральных ЭВМ. В свободное время он фотографирует, упражняется в боевых искусствах и занимается независимыми проектами.



01.08.2007

Введение

Почтовая сессия - это ресурс JavaMail. JavaMail - это API, который моделирует систему электронной почты. В отличие от API JMS, освещенном в Части 2 данного цикла, сообщения, обрабатываемые JavaMail, предназначены для использования человеком. API JavaMail реализуется третьей стороной, такой как Sun. Однако Geronimo также имеет свою собственную реализацию, и она достаточно развита, чтобы независимо отсылать электронные сообщения.

Эта статья продолжает Часть 2, на которой мы остановились. Вы создадите новый компонент JavaServer Pages (JSP), который позволяет пользователю контактировать с клиентами в специальной группе интересов через электронную почту. Это электронное сообщение затем будет послано с сервера приложений Geronimo на Apache James Mail Server 2.2. Далее, чтобы проверить новые функции, вы создадите консольный клиент для чтения сообщений электронной почты с сервера James.

Утилита Customer Service, включенная в данный цикл, - это простое Web-приложение, которое позволяет пользователям сохранять основную информацию о клиентах в базу данных. Вы создадите ее, используя Ant 1.6.5 и Java 1.4.2_10, и развернете в Geronimo 1.1 с помощью Tomcat. Вы будете использовать и базу данных Apache Derby и JMS-провайдер ActiveMQ, которые поставляются вместе с Geronimo.


Настройка James

Почтовый сервер Apache James поставляется с базовой конфигурацией, достаточной для простых тестов:

  1. Установите приложение в нужную директорию, а затем назовите его JAMES_HOME.
  2. Запустите James, вызвав в консоли выполнение кода из JAMES_HOME/bin/run.bat. Рисунок 1 показывает, как выглядит консоль после запуска James.
  3. Остановите James, нажав Ctrl+C в консоли.
  4. Измените директории на JAMES_HOME/work/james-<id, сгенерированный системой>/SAR-INF/lib. Эта директория создается только после первого запуска James. Скопируйте файлы activation.jar и mail-1.3.1.jar в JAMES_HOME/lib.
  5. Перезапустите James и отметьте номера портов, особенно для Remote Manager Service.
  6. Предполагая, что James установлен на локальной машине, подключитесь к Remote Manager Service, введя telnet localhost 4555. Используйте установленные по умолчанию логин и пароль: root и root.
  7. Создавайте аккаунты и пароли пользователей вводом adduser [пользователь] [пароль]. Например, ввод adduser smith smith создает пользователя по имени smith с паролем smith. Повторите этот пункт столько раз, сколько это необходимо.
  8. Наконец, измените файл CustomerService/resource/build.properties для Части 3, чтобы он отражал действительное расположение и Geronimo и James.
Рисунок 1. James, запущенный в консоли Windows
James, запущенный в консоли Windows

Почтовый сервер James теперь готов получать электронную почту из Geronimo. По умолчанию конфигурационный файл расположен в JAMES_HOME/apps/james/SAR-INF/config.xml. Для данной статьи не требуется изменять этот файл; он упомянут на тот случай, если вы захотите подробнее изучить параметры James.

Далее нужно создать или отредактировать тестовые учетные записи пользователей в базе данных Geronimo. Обратитесь к утилите Customer Service на http://localhost:8080/service, затем перейдите на страницу Customer Processing и создайте пользователя с адресом электронной почты на localhost, подобно показанному на рисунке 2.

Рисунок 2. Обновленный электронный адрес Джона Смита
Обновленный электронный адрес Джона Смита

Здесь у пользователя по имени Джон Смит только что обновился адрес электронной почты. Заметьте, что именем домена является localhost. Это совпадает с базовой конфигурацией James, которая ожидает этого имени домена при получении входящей почты для данного человека. Следующий шаг - объявление почтовой сессии в JNDI. Этот шаг подробно описывается в следующем разделе.


Создание дескрипторов развертывания Geronimo

Конфигурирование файлов дескриптора важно, так как именно этот механизм обеспечивает использование этих компонентов в Geronimo. Кроме того, этот механизм реализует связь JNDI-имен с конкретными объектами Java. Компоненты, развернутые в Geronimo, обычно имеют два файла развертывания: стандартный дескриптор развертывания платформы Java 2 Enterprise Edition (J2EE), или Java Enterprise Edition (Java EE) и специальный план развертывания Geronimo.

Новый JSP-интерфейс позволяет пользователю посылать электронные сообщения клиентам из отдельной группы интересов. Это электронное сообщение посылается из CustomerServiceJavaBean Web-уровня. Листинг 1 содержит дополнительный тег, необходимый для того, чтобы задать ресурс JavaMail в стандартном дескрипторе развертывания web.xml платформы J2EE/Java EE.

Листинг 1. Частичный листинг web.xml
   <resource-ref>
      <res-ref-name>mail/CustomerServiceMailSession</res-ref-name>
      <res-type>javax.mail.Session</res-type>
      <res-auth>Container</res-auth>
      <res-sharing-scope>Shareable</res-sharing-scope>
   </resource-ref>

Тег <resource-ref> привязывает JNDI-имя к типу объекта ресурса, в данном случае - javax.mail.Session. Он выглядит знакомым, так как тот же тег используется для объявления типов объектов для других типов ресурсов, таких как источники данных (для JDBC) или фабрики соединений (для JMS). Оба эти типа ресурсов уже использовались в другом месте в примере приложения. Листинг 2 содержит тег, необходимый в соответствующем специальном плане Geronimo.

Листинг 2. Частичный листинг geronimo-web.xml
   <resource-ref>
      <ref-name>mail/CustomerServiceMailSession</ref-name>
      <resource-link>mail/CustomerServiceMailGBean</resource-link>
   </resource-ref>

Тег <ref-name> соответствует тегу <res-ref-name> в web.xml, а также является JNDI-именем, по которому будет вызываться данный ресурс почтовой сессии. Тег <resource-link> задает имя для MailGBean, который отвечает за создание JavaMail-сессий. Это имя объявляется на уровне приложения и содержится в листинге 3.

Листинг 3. Листинг geronimo-appliction.xml
<application 
xmlns="http://geronimo.apache.org/xml/ns/j2ee/application-1.1">
   <dep:environment 
xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.1">
      <dep:moduleId>
         <dep:groupId>default</dep:groupId>
         <dep:artifactId>CustomerService</dep:artifactId>
         <dep:version>1.0</dep:version>
         <dep:type>ear</dep:type>
      </dep:moduleId>

      <dep:dependencies>
         <dep:dependency>
            <dep:groupId>geronimo</dep:groupId>
            <dep:artifactId>geronimo-mail</dep:artifactId>
            <dep:version>1.1</dep:version>
            <dep:type>jar</dep:type>
         </dep:dependency>

         <dep:dependency>
            <dep:groupId>geronimo</dep:groupId>
            
<dep:artifactId>geronimo-javamail-transport</dep:artifactId>
            <dep:version>1.1</dep:version>
            <dep:type>jar</dep:type>
         </dep:dependency>
      </dep:dependencies>

      <dep:hidden-classes/>
      <dep:non-overridable-classes/>
   </dep:environment>

   <module>
      <connector>tranql-connector-1.2.rar</connector>
      <alt-dd>CustomerServicePool-alt.xml</alt-dd>
   </module>

   <gbean name="mail/CustomerServiceMailGBean" 
class="org.apache.geronimo.mail.MailGBean">
      <attribute name="transportProtocol">smtp</attribute>
      <attribute name="useDefault">false</attribute>
      <attribute name="host">localhost</attribute>
      <attribute name="properties">
         mail.debug=true
         mail.smtp.port=25
      </attribute>   
   </gbean>
</application>

Необходимы два тега <dependency> для geronimo-mail-1.1.jar и geronimo-javamail-transport-1.1.jar, так как они содержат реализации для MailGBean и Transport, соответственно. Они оба нужны для поддержки объявления <gbean>. Имя этого <gbean> - это то же имя, что задано в <resource-link> geronimo-web.xml, приведенном ранее.

Атрибут transportProtocol задает протокол, smtp, который будет отсылать электронные сообщения. Атрибут host задает имя домена или IP-адрес, по которому расположен почтовый сервер. Для данной статьи James установлен на той же машине, что и Geronimo 1.1. В другом случае может быть использован любой доступный почтовый сервер, который правильно сконфигурирован, и вместо localhost могут быть использованы реальные адреса электронной почты. Атрибут properties позволяет устанавливать любые дополнительные атрибуты, используя пары имя/значение. В данном случае отладочные сообщения отображаются в консоли вывода Geronimo. smtp port соответствует тому же порту на James Mail Server. Наконец, область действия этого <gbean> ограничена только уровнем приложения, так как он задан в дескрипторах уровня приложения. Теперь, поскольку соответствующие компоненты сконфигурированы, пришло время отыскать эти объекты в коде, используя JNDI.


Утилита Customer Service и JavaMail

Усовершенствованная утилита Customer Service уже почти готова. Следующим шагом будет вызов почтовой сессии с использованием JNDI и использование JavaMail для отсылки сообщений. Полные JNDI-строки отображены в листинге 4.

Листинг 4. Листинг JNDI-имен в customer.properties
# Задайте здесь JNDI имена
jndi.customer.ejb=java:/comp/env/ejb/CustomerEntityBean
jndi.process.ejb=java:/comp/env/ejb/ProcessCustomerSessionBean
jndi.group.ejb=java:/comp/env/ejb/InterestGroupEntityBean
jndi.jms.connector=java:comp/env/jms/CustomerServiceConnectionFactory
jndi.jms.topic=java:comp/env/jms/CustomerServiceTopic
jndi.mail.session=java:comp/env/mail/CustomerServiceMailSession

Имя, объявленное ранее в теге <ref-name> дескрипторов Web-архива, теперь выводится в полном контексте JNDI-имени. Все имена сопровождены приставками согласно соглашению J2EE о наименованиях. Код в листинге 5 показывает, как проводить поиск CustomerServiceMailSession с использованием полного контекста JNDI-имени.

Листинг 5. Частичный листинг CustomerServiceJavaBean.java, производящего отыскание JNDI
public CustomerServiceJavaBean()
   {
      InitialContext initial = null;
      Object objref = null;

      bundle = ResourceBundle.getBundle("customer", Locale.getDefault(), 
CustomerServiceJavaBean.class.getClassLoader());
      JNDI_PROCESS_EJB = bundle.getString("jndi.process.ejb");
      JNDI_MAIL_SESSION = bundle.getString("jndi.mail.session");

      try
      {
         initial = new InitialContext();
         objref = initial.lookup(JNDI_PROCESS_EJB);
         processHome = (ProcessCustomerHome)PortableRemoteObject.narrow(objref, 
ProcessCustomerHome.class);
         System.out.println("looking up: " + JNDI_PROCESS_EJB);

         objref = initial.lookup(JNDI_MAIL_SESSION);
         mailSession = (Session)PortableRemoteObject.narrow(objref, 
javax.mail.Session.class);
         System.out.println("looking up: " + JNDI_MAIL_SESSION);
      } // end try

      catch (Exception e)
      {
         e.printStackTrace();
      } // end catch
   } // end CustomerServiceJavaBean

Должно быть очевидным, что код для поиска почтовых сессий похож на код для поиска ProcessCustomerSessionBean. Единственные части, которые необходимо изменить - это те, которые ссылаются на почтовые сессии. Листинг 6 содержит код, необходимый для отсылки фактического электронного сообщения из Geronimo.

Листинг 6. Частичный листинг CustomerServiceJavaBean.java, отсылающего электронные сообщения
private boolean sendEmail(String toAddress, String fromAddress, String 
subject, String content)
   {
      boolean status = false;

      try
      {
         Date dateStamp = new Date();
         MimeMessage email = new MimeMessage(mailSession);

         email.setFrom(new InternetAddress(fromAddress));
         email.setRecipients(Message.RecipientType.TO,
                             InternetAddress.parse(toAddress, false));
         email.setSubject(subject);
         email.setText(content);
         email.setHeader("X-Mailer", "JavaMailer");
         email.setSentDate(dateStamp);

         Transport.send(email);
         status = true;
      } // end try

      catch (Exception e)
      {
         status = false;
         e.printStackTrace();
      } // end catch

      return status;
   } // end sendEmail

Опять CustomerServiceJavaBean является частью Web-слоя, а с точки зрения этого слоя электронные сообщения отсылает Geronimo. mailSession получается через поиск JNDI, показанный в предыдущем листинге, и используется для создания MimeMessage, который является фактическим объектом, представляющим электронное сообщение. После настройки соответствующих атрибутов, сообщение отсылается на почтовый сервер через объект Transport.

Вы захотите проверить, что сообщения успешно получены почтовым сервером. Чтобы сделать это, вам нужен клиент, основанный на консоли, который может подключиться к почтовому серверу, извлечь все сообщения, предназначенные для данного пользователя, и просто вывести содержимое каждого сообщения в консоль. Листинг 7 содержит частичный листинг этого клиента, названного Reader, который создает почтовые сессии.

Листинг 7. Метод Reader.java для создания JavaMail сессий
private Session generateSession(String host, String user, String password)
   {
      authentication = new PasswordAuthentication(user, password);

      Properties properties = new Properties();
      properties.put("mail.host", host);
      properties.put("mail.debug", "false");
      properties.put("mail.user", user);
      properties.put("mail.store.protocol", "pop3");

      Session session = Session.getInstance(properties, this);

      return session;
   } // end generateSession

PasswordAuthentication проверяет данные - имя пользователя и пароль. Учтите, что этот метод не применяет JNDI. Вместо этого, он задает соответствующие свойства, которые затем используются для создания почтовых сессий. Листинг 8 показывает фактический код, который извлекает электронные сообщения.

Листинг 8. Метод Reader.java для чтения всех входящих электронных сообщения для данного пользователя
protected void readEmail(String host, String username, String password)
   {
      Store store = null;
      Folder inbox = null;

      try
      {
         Session mailSession = generateSession(host, username, password);

         store = mailSession.getStore();
         store.connect();
         Folder folder = store.getDefaultFolder();
         inbox = folder.getFolder("inbox");

         inbox.open(Folder.READ_ONLY);
         Message[] messages = inbox.getMessages();

         System.out.println("Inbox for userID: " + username);
         System.out.println("inbox size: " + messages.length);
         System.out.println("*****");

         for (int x = 0; x < messages.length; x++)
         {
            MimeMessage email = (MimeMessage)messages[x];

            System.out.println("FROM: " + email.getFrom()[0].toString());
            System.out.println("TO: " + 
email.getRecipients(Message.RecipientType.TO)[0].toString());
            System.out.println("DATE: " + email.getSentDate());
            System.out.println("SUBJECT: " + email.getSubject());
            System.out.println("CONTENT: " + email.getContent());
         } // end for

         System.out.println("*****");
      } // end try

      catch (Exception e)
      {
         e.printStackTrace();
      } // end catch

      finally
      {
         try
         {
            inbox.close(true);
            store.close();
         } // end try

         catch (Exception e)
         {
            e.printStackTrace();
         } // end catch
      } // end finally
   } // end readEmail

После того, как почтовая сессия создана, она используется для получения банка сообщений, который соединяется с почтовым сервером. Inbox - это зарезервированное имя папки, и когда соединение установлено, все сообщения могут быть найдены в данной папке. После того, как сообщения найдены, отобразить их содержимого в консоли уже просто.

Теперь утилита Customer Service готова к развертыванию в Geronimo:

  1. Измените файл CustomerService/resources/build.properties и убедитесь, что расположение каталогов описано правильно.
  2. Откройте консоль и измените директории на местоположение CustomerService/build.xml, введите ant. Это создает и развертывает приложение, к которому можно обратиться на http://localhost:8080/service. Это также упаковывает приложение клиента Reader. Рисунок 3 показывает, как выглядит страница Groups Contact.
Рисунок 3. Отправка клиентам электронных сообщений через страницу Groups Contact
Отправка клиентам электронных сообщений через страницу Groups Contact

Здесь пользователь нашел всех клиентов в специальной Java-группе интересов. Теперь пользователь решил послать электронное сообщение клиенту - Джону Смиту. При необходимости пользователь может выбрать всех отображенных клиентов, и то же самое электронное сообщение будет послано каждому из них, при условии, что имя домена (localhost) валидно и их идентификаторы пользователя были созданы на почтовом сервере. После того, как электронное сообщение послано, в консоли вывода Geronimo появляются отладочные сообщения, такие как на рисунке 4.

Рисунок 4. Консоль Geronimo с отладочными сообщениями JavaMail
Консоль Geronimo с отладочными сообщениями JavaMail

Согласно показанным выше результатам, сообщение Джону Смиту было успешно послано в James Mail Server. Следующим шагом будет проверить, чтобы почтовый сервер подтвердил, что электронное сообщение постоянно хранится в James. Запустите Reader со следующим: client localhost smith smith. Это должно вывести результат как на рисунке 5.

Рисунок 5. Выходные данные клиента для электронной почты, полученной от James
Выходные данные клиента для электронной почты, полученной от James

Все сообщения, посланные Джону Смиту со страницы Group Contacts, должны быть отображены в выходных данных пользователя. Электронные сообщения, посланные из Geronimo, были успешно посланы в James Mail Server. Вот и все, что нужно для доступа к ресурсам JavaMail в JNDI!


Выводы

В данной статье вы узнали, как конфигурировать и вызывать группу ресурсов JavaMail. Утилита Customer Service показывает, как обращаться к этому ресурсу из JNDI, посылая электронное сообщение клиентам из Web-интерфейса в Apache James Mail Server. Затем вы реализовали специальное консольное приложение для проверки того, что входящее электронное сообщение получено. Следующая и последняя статья в данном цикле будет обсуждать доступ JNDI к URL-соединениям, которые вы будете использовать для завершения утилиты Customer Service.


Загрузка

ОписаниеИмяРазмер
Исходный код программы, Часть 3CustomerService-part3.zip589KB

Ресурсы

Научиться

Получить продукты и технологии

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Open source, Технология Java, WebSphere
ArticleID=244151
ArticleTitle=Присвоение имен JNDI в Apache Geronimo и пулы подключений ресурсов Java, Часть 3: Почтовые сессии
publish-date=08012007