Опубликован: 10.10.2010 | Уровень: специалист | Доступ: платный
Лекция 13:

Использование 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 of
40               * 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  }
Листинг 13.5. Класс BillingClient

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

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

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

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  }
Листинг 13.6. Класс Card

Транспортный класс 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  }
Листинг 13.7. Класс CardOperation

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

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

Для обработки (получения) сообщений он регистрирует Objectlistener.

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  }
Листинг 13.8. Класс BillingService

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

Алмаз Мурзабеков
Алмаз Мурзабеков
Прохожу курс "Построение распределенных систем на Java" в третьей лекции где описывается TCPServer вылетает эта ошибка
"Connection cannot be resolved to a type"


Java version 1.7.0_05
Игорь Шаталов
Игорь Шаталов
Украина, Донецк, Донецкий национальный университет, 2012