asadmin.bat create-jms-resource --user admin --passwordfile




Admin-password.txt --host localhost --port 4848 --restype

javax.jms.Queue --enabled=true --property Name=PhysicalQueue

Jms/Exаmple1Queue

 

Как и в случае с ConnectionFactory,созданный объект доступен в административной консоли.

Теперь, после того как все необходимые ресурсы созданы, можно приступить к созданию прило­жения. В качестве первого примера мы разработаем простое приложение, которое со­стоит из двух компонентов, обменивающихся текстовыми сообщениями в синхронном ре­жиме.

JMSClient

 

Класс JMSClient (листинг 1)после своего запуска создает соединение с JMS -провай­дером, созда­ет сес­сию и MessageProducer, после чего в ответ на каждый ввод пользователя посылает в очередь текстовое сообщение. Работа завершается, если пользователь ввел символ q (или Q).

 

Листинг 1

import javax.jms.ConnectionFactory;import javax.jms.Destination;import javax.jms.Queue;import javax.jms.Topic;import javax.jms.Connection;import javax.jms.Session;import javax.jms.MessageProducer;import javax.jms.TextMessage;import javax.jms.JMSException;import javax.annotation.Resource;import java.io.InputStreamReader;import java.io.IOException; public class JMSClient { @Resource(mappedName = "jms/Example1ConnectionFactory") private static ConnectionFactory connectionFactory; @Resource(mappedName = "jms/Example1Queue") private static Queue queue; public static void main(String[] args) { Connection connection = null; Destination dest = (Destination) queue; try { connection = connectionFactory.createConnection(); Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE); MessageProducer producer = session.createProducer(dest); TextMessage message = session.createTextMessage(); InputStreamReader inputStreamReader = new InputStreamReader(System.in); char c = 'n'; int i = 0; while (!((c == 'q') || (c == 'Q'))) { try { c = (char) inputStreamReader.read(); message.setText("This is message " + (i + 1)); System.out.println("Sending message: " + message.getText()); producer.send(message); i++; } catch (IOException e) { System.err.println("I/O exception: " + e.toString()); } } } catch (JMSException e) { System.err.println("Exception occurred: " + e.toString()); } finally { if (connection!= null) { try { connection.close(); } catch (JMSException e) { } } } }}

 

Программа демонстрирует весь цикл создания типичного JMS -приложения.

Сначала определяются необходимые ресурсы - в данном случае ConnectionFactory и Queue (эти ресурсы с соответствующими именами были ранее созданы).

Затем создаются соединение с JMS -провайдером и сессия.

Следую­щим шагом является создание MessageProducer и текстового сообщения.

Цикл работы программы состоит в ожидании ввода пользователя, формировании тела сообщения и его отправки в очередь.

В конце ра­боты программа закрывает соединение с JMS -провайдером.

JMSServer

 

Существует два пути получения сообщений:

1. Синхронное затребование сообщений из queue, используя метод receive() интерфейса javax.jms.QueueReceiver.

2. Асинхронное получение сообщений как только они становятся доступны – используя интерфейс javax.jms.MessageListener.

Используем первый способ. В этом случае класс JMSServer (листинг 2)служит для обработки сообщений, отправляемых для JMSClient. Он синхрон­ным образом считывает сообщения из очереди и печатает их.

import javax.jms.ConnectionFactory;import javax.jms.Destination;import javax.jms.Queue;import javax.jms.Connection;import javax.jms.Session;import javax.jms.MessageConsumer;import javax.jms.Message;import javax.jms.TextMessage;import javax.jms.JMSException;import javax.annotation.Resource; public class JMSServer { @Resource(mappedName = "jms/Example1ConnectionFactory") private static ConnectionFactory connectionFactory; @Resource(mappedName = "jms/Example1Queue") private static Queue queue; public static void main(String[] args) { String destType = null; Connection connection = null; Session session = null; Destination dest = (Destination) queue;; MessageConsumer consumer = null; TextMessage message = null; try { connection = connectionFactory.createConnection(); session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); consumer = session.createConsumer(dest); connection.start(); while (true) { Message m = consumer.receive(1); if (m!= null) { if (m instanceof TextMessage) { message = (TextMessage) m; System.out.println("Reading message: " + message.getText()); } } } } catch (JMSException e) { System.err.println("Exception occurred: " + e.toString()); } finally { if (connection!= null) { try { connection.close(); } catch (JMSException e) { } } } }}

Отличие от предыдущего класса заключается в том, что создается не MessageProducer, а MessageConsumer, поскольку мы собираемся не отправлять сообщения, а прини­мать их.

Для того чтобы начать обработку сообщений, необходимо вызвать метод start.

Цикл работы программы состоит в ожидании прихода нового сообщения. В данном слу­­чае ожидание продолжается 1 миллисекунду.

Если пришедшее сообще­ние имеет текстовый тип (именно такие сообщения мы ожидаем получить), оно извлека­ется и печатается тело сообщения.

Компиляция и запуск

 

Компиляция приложений JMS не имеет особенностей, единственное, что нужно сделать, - указать соответствующие библиотеки в classpath:

javac –classpath.;activation.jar;appserv-ws.jar;javaee.jar; jsfimpl.jar;appserv-jstl.jar; -d build JMSClient.java

 

Затем нужно собрать соответствующие пакеты (jar):

jar -cvfm server.jar manifest2.mf -C./build. jar -cvfm client.jar manifest.mf -C./build.

 

При этом файлы манифеста имеют следующий вид:

 

manifest.mf

 

Manifest-Version: 1.0 Ant-Version: Apache Ant 1.6.5 Created-By: aswMain-Class: JMSClient

manifest2.mf

 

Manifest-Version: 1.0 Ant-Version: Apache Ant 1.6.5 Created-By: asw Main-Class: JMSServer

 

В результате будут созданы два пакета: server.jar и client.jar.

Запуск приложения произво­дится с помощью утилиты appclient, соответственно:

appclient -client client.jar

 

для клиента (отправителя сообщений) и

appclient -client server.jar

 

для сервера (обработчика сообщений).

После запуска клиент в ответ на ввод пользователя будет посылать сообщения в очередь, сер­вер будет их принимать и печатать.

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

Ниже приведен пример работы системы.

appclient -client client.jar

 

Запуск клиента приведет к выводу сообщений об отправке.

Sending message: This is message 1Sending message: This is message 2Sending message: This is message 3Sending message: This is message 4Sending message: This is message 5Sending message: This is message 6Sending message: This is message 7Sending message: This is message 8Sending message: This is message 9Sending message: This is message 10

 

Запуск сервера:

 

appclient -client server.jar

 

приведет к выводу сообщений о приеме.

Reading message: This is message 1Reading message: This is message 2Reading message: This is message 3Reading message: This is message 4Reading message: This is message 5Reading message: This is message 6Reading message: This is message 7Reading message: This is message 8Reading message: This is message 9Reading message: This is message 10

 

Пример создания JMS -базированной КИС

 

Теперь, после того как основные концепции JMS проиллюстрированы, мы можем приступить к реализации системы, обеспечивающей решение поставленной нами задачи с испо­льзова­нием механизмов JMS.

Как обычно, система будет состоять из двух компонентов:

- клиентского, передающего данные о новых картах и операциях над ними;

- серверного, принимающего и обрабатывающего эти данные.

Для передачи данных мы воспользуемся сообщениями типа ObjectMessage и транспор­т­ными классами, которые будут поддерживать механизм сериализации. Кроме этого, в серверном компоненте будет реализован асинхронный механизм обработки сообщений, с испо­льзова­нием соответствующего листенера.

Перед компиляцией и выполнением примера необходимо создать соответствующие ре­сурсы: ConnectionFctory и Queue с именами jms/ConnectionFactory и jms/Queue соответственно.

Клиентский класс BillingClient

1 package com.asw.jms.ex1;2 3 import javax.jms.*;4 import javax.annotation.Resource;5 import java.util.Date;6 7 public class BillingClient {8 @Resource(mappedName = "jms/ConnectionFactory")9 private static ConnectionFactory connectionFactory;10 @Resource(mappedName = "jms/Queue")11 private static Queue queue;12 13 public static void main(String[] args) {14 Connection connection = null;15 Destination dest = (Destination) queue;16 try {17 connection = connectionFactory.createConnection();18 Session session = connection.createSession(false,19 Session.AUTO_ACKNOWLEDGE);20 MessageProducer producer = session.createProducer(dest);21 ObjectMessage message = session.createObjectMessage();22 Card c = new Card ("Piter",new Date(),"1",0.0);23 message.setObject(c);24 producer.send(message);25 c = new Card("Stefan",new Date(),"2",0.0);26 message.setObject(c);27 producer.send(message);28 c = new Card("Nataly",new Date(),"3",0.0);29 message.setObject(c);30 producer.send(message);31 int cnt = 1000;32 for (int i = 0; i < cnt; i++) {33 CardOperation co = new CardOperation ((i%3+1)+"",10+i,new Date());34 message.setObject(co);35 System.out.println("Sending message: " + message.getObject());36 producer.send(message);37 }38 /*39 * Send a non-text control message indicating end of40 * messages.41 */42 producer.send(session.createMessage());43 } catch (JMSException e) {44 System.err.println("Exception occurred: " + e.toString());45 } finally {46 if (connection!= null) {47 try {48 connection.close();49 } catch (JMSException e) {50 }51 }52 }53 }54 }

 

Отличие от рассмотренного ранее примера состоит в том, что создается сообщение типа ObjectMessage (строка 21). Для помещения объекта в тело этого сообщения необходимо вы­звать метод setObject (конечно, класс, объект которого помещается в сообщение, должен быть объявлен как реализующий интерфейс Serializable).

Транспортный класс Card

 

Транспортные классы Card и CardOperation полно­стью аналогичны рассматриваемым ранее.

 

Класс Card

1 package com.asw.jms.ex1;2 3 import java.io.Serializable;4 import java.util.*;5 6 7 public class Card implements Serializable{8 public Card(String person, Date createDate, String cardNumber,double balance){9 this.person = person;10 this.createDate = createDate;11 this.cardNumber = cardNumber;12 this.balance = balance;13 }14 public String person;15 public Date createDate;16 public String cardNumber;17 public double balance;18 public String toString(){19 return "Card: cardNumber = "+cardNumber+"\tBalance="+balance+ "\tPerson="+person+"\tCreateDate="+createDate+"";20 }21 }

Транспортный класс CardOperation

1 package com.asw.jms.ex1;2 3 import java.util.*;4 import java.io.*;5 6 public class CardOperation implements Serializable {7 public CardOperation(String card,double amount,Date operationDate){8 this.card = card;9 this.amount = amount;10 this.operationDate = operationDate;11 }12 public String card;13 public double amount;14 public Date operationDate;15 }

Серверный класс BillingService

 

Серверный класс содержит методы, обеспечивающие выполнение операций с картами, и является контейнером для хранения карт.Для обработки (получения) сообщений он регистрирует Objectlistener.

 

Класс BillingService

1 package com.asw.jms.ex1;2 3 import javax.jms.*;4 import javax.annotation.Resource;5 import java.io.InputStreamReader;6 import java.io.IOException;7 import java.util.Hashtable;8 import java.util.Enumeration;9 10 public class BillingService {11 @Resource(mappedName = "jms/ConnectionFactory")12 private static ConnectionFactory connectionFactory;13 @Resource(mappedName = "jms/Queue")14 private static Queue queue;15 16 Hashtable hash = new Hashtable();17 public void addNewCard(Card c) {18 hash.put(c.cardNumber, c); 19 };20 21 public void performCardOperation(CardOperation co){22 Card c = (Card)hash.get(co.card);23 if (c==null) return;24 c.balance+=co.amount;25 hash.put(co.card,c);26 };27 28 public void printCards(){29 for(Enumeration e = hash.elements();e.hasMoreElements();)30 System.out.println(e.nextElement());31 }32 33 public static void main(String[] args) {34 String destType = null;35 Connection connection = null;36 Session session = null;37 Destination dest = (Destination) queue;38 MessageConsumer consumer = null;39 ObjectListener listener = null;40 TextMessage message = null;41 InputStreamReader inputStreamReader = null;42 char answer = '\0';43 try {44 connection = connectionFactory.createConnection();45 session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);46 consumer = session.createConsumer(dest);47 listener = new ObjectListener(new BillingService());48 consumer.setMessageListener(listener);49 connection.start();50 System.out.println(51 "To end program, type Q or q, " + "then <return>");52 inputStreamReader = new InputStreamReader(System.in);53 while (!((answer == 'q') || (answer == 'Q'))) {54 try {55 answer = (char) inputStreamReader.read();56 } catch (IOException e) {57 System.err.println("I/O exception: " + e.toString());58 }59 }60 } catch (JMSException e) {61 System.err.println("Exception occurred: " + e.toString());62 } finally {63 if (connection!= null) {64 try {65 connection.close();66 } catch (JMSException e) {67 }68 }69 }70 }71 }

 

После создания соединения с JMS-провайдером (строка 44) и создания сессии (строка 45) создается MessageConsumer (строка 46). Затем создается ObjectListener (строка 47) и регистриру­ется в MessageConsumer как принимающий сообщения (строка 48). Таким образом, при приходе нового сообщения в очередь будет вызываться метод onMessage листенера, кото­рый и будет обрабатывать сообщение. Метод start (строка 49) запускает обработку сообще­ний.

Серверный листенер ObjectListener

ObjectListener обрабатывает поступающие сообщения. При приходе нового сообщения он проверяет его тип (сообщение должно быть типа ObjectMessage,приход тексто­вого сооб­щения интерпретируется как команда выдать балансы всех карт), извлекает объект, передан­ный в теле сообщения, проверяет его тип (ожидается, что пришедшие объекты могут быть двух типов - Card и CardOperation),после чего вызывает соответствующий метод Billing­Ser­vice,выполняющий нужную операцию.

Класс ObjectListener

1 package com.asw.jms.ex1;2 3 import javax.jms.*;4 5 6 public class ObjectListener implements MessageListener {7 BillingService bs;8 public ObjectListener (BillingService bs){9 this.bs = bs;10 }11 public void onMessage(Message message) {12 ObjectMessage msg = null;13 14 try {15 if (message instanceof ObjectMessage) {16 msg = (ObjectMessage) message;17 Object o = msg.getObject();18 System.out.println("Reading message: " + o);19 if (o instanceof Card) bs.addNewCard((Card)o);20 else if (o instanceof CardOperation) bs.performCardOperation((CardOperation)o);21 } else {22 System.err.println("Message is not a ObjectMessage");23 bs.printCards();24 }25 } catch (JMSException e) {26 System.err.println("JMSException in onMessage(): " + e.toString());27 } catch (Throwable t) {28 System.err.println("Exception in onMessage():" + t.getMessage());29 }30 }31 }

Компиляция и запуск

 

Компиляция и выполнение не отличаются от рассмотренного ранее примера. Ниже приведен пример работы системы. Запуск клиента:

appclient -client BillingClient.jar

 

Результат выполнения клиентской программы приведен ниже:

Sending message: com.asw.jms.ex1.CardOperation@1e0bf98....Sending message: com.asw.jms.ex1.CardOperation@11fb8c6Sending message: com.asw.jms.ex1.CardOperation@35378dSending message: com.asw.jms.ex1.CardOperation@190c5c0Sending message: com.asw.jms.ex1.CardOperation@1681629Sending message: com.asw.jms.ex1.CardOperation@1c39aa6Sending message: com.asw.jms.ex1.CardOperation@44c4a4Sending message: com.asw.jms.ex1.CardOperation@469729

 

Запуск сервера:

appclient -client BillingService.jar

 

Результат выполнения серверной программы приведен ниже:

To end program, type Q or q, then <return>Reading message: Card: cardNumber=1 Balance=0.0 Person=PiterCreateDate=Sun Dec 24 13:13:15 MSK 2006Reading message: Card: cardNumber=2 Balance=0.0 Person=StefanCreateDate=Sun Dec 24 13:13:15 MSK 2006Reading message: Card: cardNumber=3 Balance=0.0 Person=NatalyCreateDate=Sun Dec 24 13:13:15 MSK 2006Reading message: com.asw.jms.ex1.CardOperation@1dbe72fReading message: com.asw.jms.ex1.CardOperation@26efd3Reading message: com.asw.jms.ex1.CardOperation@1c20611Reading message: com.asw.jms.ex1.CardOperation@11c5c88... Reading message: com.asw.jms.ex1.CardOperation@11ce4fe Reading message: com.asw.jms.ex1.CardOperation@1fe0d66 Card: cardNumber=3Balance=169830.0 Person=Nataly CreateDate=SunDec 24 13:13:15 MSK 2006Card: cardNumber=2Balance=169497.0 Person=Stefan CreateDate=SunDec 24 13:13:15 MSK 2006Card: cardNumber=1Balance=170173.0 Person=PiterCreateDate=Sun Dec24 13:13:15 MSK 2006

 

План выполнения лабораторной работы:

 

Часть 1.

1. Ознакомиться с принципами удаленного взаимодействия объектов Java в рамках RMI.

2. Ознакомиться и разобрать предлагаемый пример Simple Time, использующий пере­дачу примитивных типов Java.

3. Реализовать пример на локальной машине.

4. Определить состав файлов, необходимый для клиента и сервера.

5. Реализовать пример в сети (используя п. 4).

6. Ознакомиться с файлами политик безопасности и добиться запуска примера в «огра­ничен­ном» режиме (факультативно).

 

Часть 2.

1. Ознакомиться с понятием сериализации объектов Java.

2. Изучить предлагаемый пример, использующий передачу пользовательского сериали­зуе­мого типа.

3. Реализовать пример в сети.

4. Создать клиент-серверную систему, использующую RMI для передачи объектов (объ­екты выбрать произвольно) в виде пары консольных приложений.

5. Реализовать пример в сети.

 

Часть 3.

1. Ознакомиться с понятием активизации серверных объектов в RMI.

2. Изучить предлагаемый пример клиент-серверной системы, использующей активиза­цию серверного объекта.

3. Реализовать пример в сетевом режиме.

 

Часть 4 (факультативно).

Реализовать графическую оболочку для клиентской части клиент-серверной системы в соот­ветствии с индивидуальным заданием. В качестве среды для построения графического приложения предлагается использовать NetBeans IDE.

Задание - создать оригинальное приложение на основе Java JMS, имеющее следующие минимальные возможности:

- подключение источника данных к приложению средствами Microsoft Visual Studio 2010;

- установка и разрыв соединения с существующей БД КИС программным способом;

- работа с БД КИС в соединённом режиме программным способом: просмотр записей вы­бранной таблицы БД, выполнение команд-запросов на получение данных таблицы БД.

- работа с БД КИС в разъединённом режиме программным способом: просмотр схемы вы­бранной таблицы БД, выполнение запросов, не возвращающих результат, редактирование выбранной таблицы БД;

- работа с БД КИС программным способом с использованием механизмов: транзак­ций, триггеров и хранимых процедур.

Указания и рекомендации:

1. Рекомендуется использование ОС Windows 7 Ultimate RTM Russian + Service Pack 1.

2. Обязательно использование языка программирования Java.

3. Рекомендуется использование системы программирования SUN ONE STUDIO 5.1 и NetBeans IDE.

4. Рекомендуется создание консольного приложения.

 

Контрольные вопросы:

 

1. Дайте определение JMS.

2. Что представляет собой корпоративная информационная система типа MOM?

3. Что называется JMS-клиентом?

4. Что называется JMS-поставщиком?

5. Что называется JMS-потребителем?

6. Что называется JMS-провайдеом?

7. Что называется JMS-приложением?

8. Что называется JMS-сообщением?

9. Какую роль выполняют управляющие объекты JMS?

10. Зачем нужны средства администрирования JMS?

11. Дайте определение термину расположение.

12. Какую роль выполняет фабрика соединения в JMS?

13. Какую роль выполняет JNDI в JMS?

14. Опишите трехуровневую архитектуру JMS.

15. Что называется JMS-провайдером?

16. Перечислите типы сообщений JMS.

17. Из каких частей состоит сообщение JMS?

18. Что означает термин несохраняемое сообщение JMS?

19. Что означает термин сохраняемое сообщение JMS?

20. Что такое Уведомления о доставке сообщений JMS?

21. Какую роль выполняет селектор сообщений JMS?

22. Для чего в JMS используются транзакции?

23. Какие разновидности механизма транзакций используются в JMS?

24. Опишите модель передачи сообщений «изда­ние - подписка».

25. Какую роль выполняет тема в модели передачи сообщений «изда­ние - подписка»?

26. Что означает термин прочная подписка?

27. Что означает термин непрочная подписка?

28. Опишите модель передачи сообщений «точка - точка».

29. Какую роль выполняет очередь в модели передачи сообщений «точка - точка»?

30. Кратко опишите схему применения JMS при разработке КИС.

 


[1] один и тот же JMS -клиент может быть одновременно и поставщиком, и потребителем в разных актах взаимодействия

[2] концепция ESB - E nterprise S ervice B us

[3] JTA - J ava T ransaction API



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-02-16 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: