Прохожу курс "Построение распределенных систем на 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) запускает обработку сообщений.