|
Прохожу курс "Построение распределенных систем на Java" в третьей лекции где описывается TCPServer вылетает эта ошибка
"Connection cannot be resolved to a type" Java version 1.7.0_05 |
Использование 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) запускает обработку сообщений.