Изучаем Java EE 7 - [212]

Шрифт
Интервал

>public void onMessage(Message message) {

>··try {

>····System.out.println("Сообщение получено: " + message.getBody(String.class));

>··} catch (JMSException e) {

>····context.setRollBackOnly();

>··}

>}

Все вместе

В этой главе мы рассмотрели основные концепции обмена сообщениями (модели P2P и pub-sub) и администрируемые объекты (фабрики соединений и места назначения), узнали, как подключиться к поставщику, производить и потреблять сообщения, использовать некоторые механизмы надежности, а также применять управляемые контейнером компоненты (MDB) для прослушивания мест назначения. Теперь посмотрим, как эти понятия работают вместе, на примере, который мы скомпилируем и упакуем с помощью Maven и развернем на GlassFish.

Будем использовать отдельный класс (OrderProducer), который посылает сообщения в тему (под названием jms/javaee7/Topic). Эти сообщения являются объектами, представляющими заказ клиента на покупку книг и компакт-дисков. Заказ (OrderDTO) имеет несколько атрибутов, в том числе и общую сумму заказа. Потребители, которые слушают тему, имеют типы OrderConsumer и ExpensiveOrderMDB (рис. 13.13). OrderConsumer получает любые заказы, но MDB потребляет только те, которые имеют общую стоимость более $1000 (это делается с помощью селектора).

Maven необходимо структурировать код, основанный на окончательных артефактах упаковки, поэтому ExpensiveOrderMDB и OrderDTO будут упакованы в один файл. jar (chapter13-MDB-1.0.jar), а затем развернуты на GlassFish. OrderProducer, OrderConsumer и опять же OrderDTO будут работать в среде Java SE.

Написание класса OrderDTO

Объект, который будет отправлен в сообщении JMS, является POJO, и для него необходимо реализовать интерфейс Serializable. Класс OrderDTO, показанный в листинге 13.14, дает некоторую информацию о заказе, в том числе об общей сумме. Он является объектом, который будет установлен в JMS ObjectMessage и отправлен из OrderProducer в тему, а затем потреблен OrderConsumer и ExpensiveOrderMDB.


Листинг 13.14. OrderDTO передается в JMS ObjectMessage

>public class OrderDTO implements Serializable {

>··private Long orderId;

>··private Date creationDate;

>··private String customerName;

>··private Float totalAmount;

>··// Конструкторы, методы работы со свойствами

>}

Написание класса OrderProducer

OrderProducer, показанный в листинге 13.15, представляет собой автономный клиент, который использует упрощенный JMS API для отправки ObjectMessage в тему jms/javaee7/Topic. Он выполняет поиск необходимых фабрик соединений и мест назначения, и в методе main() создает экземпляр класса OrderDTO. Обратите внимание, что параметр totalAmount заказа — это аргумент, передаваемый классу (args[0]). JSMProducer устанавливает свойство сообщения orderAmount, чтобы позволить выполнять выборку сообщений далее, и заказ затем отправляется в тему.


Листинг 13.15. OrderProducer посылает заказ в OrderDTO

>public class OrderProducer {

>··public static void main(String[] args) throws NamingException {

>····// Создает объект orderDto с параметром totalАmount

>····Float totalAmount = Float.valueOf(args[0]);

>····OrderDTO order = new OrderDTO(1234l, new Date(), "Бетти Мореу", totalAmount);


>····// Получает контекст JNDI

>····Context jndiContext = new InitialContext();


>····// Поиск администрируемых объектов

>····ConnectionFactory connectionFactory = (ConnectionFactory) 

>······················jndiContext.lookup("jms/javaee7/ConnectionFactory");

>····Destination topic = (Destination) jndiContext.lookup("jms/javaee7/Topic");


>····try (JMSContext jmsContext = connectionFactory.createContext()) {

>·····// Посылает сообщение в тему

>·····jmsContext.createProducer(). setProperty("orderAmount", totalAmount). send(topic, order);

>····}

>··}

>}

Написание OrderConsumer

OrderConsumer, показанный в листинге 13.16, также является отдельным клиентом JMS, который слушает тему jms/javaee7/Topic и использует JMSConsumer API, чтобы получить все OrderDTO (без селекторов).


Листинг 13.16. OrderConsumer потребляет все сообщения OrderDTO

>public class OrderConsumer {

>··public static void main(String[] args) throws NamingException {


>····// Получение контекста JNDI

>····Context jndiContext = new InitialContext();


>····// Выполняется поиск администрируемых объектов

>····ConnectionFactory connectionFactory = (ConnectionFactory) 

>······················jndiContext.lookup("jms/javaee7/ConnectionFactory");

>····Destination topic = (Destination) jndiContext.lookup("jms/javaee7/Topic");


>····// Цикл получения сообщений

>····Try (JMSContext jmsContext = connectionFactory.createContext()) {

>······while (true) {

>········OrderDTO order = jmsContext.createConsumer(topic). receiveBody(OrderDTO.class);

>········System.out.println("Заказ получен: " + order);

>······}

>····}

>··}

>}

Написание класса ExpensiveOrderMDB

Класс ExpensiveOrderMDB (листинг 13.17) является MDB с аннотацией @MessageDriven, который слушает место назначения jms/javaee7/Topic. Этот MDB интересуют только заказы, сумма которых больше $1000, что достигается с помощью селектора сообщений (orderAmount > 1000). По прибытии сообщения метод onMessage() потребляет его, приводит к типу OderDTO (getBody(OrderDTO.class)) и получает тело сообщения. В данном примере только отображается сообщение (system.out.println), но может быть и другая обработка (например, путем ее делегирования сессионному компоненту, не сохраняющему состояние).


Рекомендуем почитать
Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


MFC и OpenGL

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Симуляция частичной специализации

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Обработка событий в С++

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.