Прохожу курс "Построение распределенных систем на Java" в третьей лекции где описывается TCPServer вылетает эта ошибка
"Connection cannot be resolved to a type" Java version 1.7.0_05 |
Web-сервисы. Примеры
Клиентский класс BillingClient
При реализации клиента первая проблема состоит в том, что вызываемые методы Web -сервиса принимают аргументы - объекты. Вторая проблема состоит в том, что некоторые из этих методов принимают массивы объектов.
Первая проблема возникает из-за того, что на самом деле клиентское приложение не получает доступа к "настоящим" классам сервера - т.е. клиент не имеет доступа к классам com.asw.ws.ex1.endpoint.Card или com.asw.ws.ex1.endpoint.CardOperation,рассмотренным в предыдущем разделе и реализованным на сервере. Вместо этого утилитой wsimport на основании анализа WSDL файла генерируются другие классы. Они тоже располагаются в пакете com.asw.ws.ex1.endpoint (но клиента) и называются так же - Card и CardOperation.Но предназначены они только для того, чтобы служить оберткой для передаваемых данных. В этих сгенерированных классах будут содержаться все поля классов исходных, но в них не будет содержаться методов, которые определены в "настоящих" классах, располагающихся на сервере. Все, что они будут содержать, - методы установки и получения соответствующих полей. По большому счету, это даже не классы, а структуры, предназначенные для передачи параметров. Ниже для иллюстрации приведен один такой сгенерированный класс для Card.
Вторая проблема возникает из-за того, что при генерации структура вида "массив объектов" (Т[]) преобразуется в "список объектов" (List<T>).Поэтому в соответствующие методы нужно передавать не массивы, а классы, производные от List,- например, Vector.
1 package com.asw.ws.ex1.client; 2 3 import javax.xml.ws.WebServiceRef; 4 import com.asw.ws.ex1.endpoint.BillingService; 5 import com.asw.ws.ex1.endpoint.Billing; 6 import com.asw.ws.ex1.endpoint.Card; 7 import com.asw.ws.ex1.endpoint.CardOperation; 8 import javax.xml.datatype.XMLGregorianCalendar; 9 import java.util.*; 10 11 public class BillingClient { 12 @WebServiceRef(wsdlLocation="http://localhost:8080/billingservice/billing?wsdl") 13 static BillingService service; 14 15 public static void main(String[] args) { 16 try { 17 BillingClient client = new BillingClient(); 18 client.startTest(); 19 } catch(Exception e) { 20 e.printStackTrace(); 21 } 22 } 23 24 public void startTest() { 25 try { 26 Billing port = service.getBillingPort(); 27 28 Vector<Card> vc = new Vector<Card>(); 29 Card c = new Card(); 30 c.setPerson("Piter"); 31 XMLGregorianCalendar dat = javax.xml.datatype.DatatypeFactory.newInstance().newXMLGregorianCalendar(); 32 dat.setYear(2006); 33 dat.setMonth(11); 34 dat.setDay(5); 35 c.setCreateDate( dat ); 36 c.setCardNumber("1"); 37 c.setBalance(0.0); 38 vc.add(c); 39 40 c = new Card(); 41 c.setPerson("Stefan"); 42 c.setCreateDate( dat ); 43 c.setCardNumber("2"); 44 c.setBalance(0.0); 45 vc.add(c); 46 47 c = new Card(); 48 c.setPerson("Nataly"); 49 c.setCreateDate( dat ); 50 c.setCardNumber("3"); 51 c.setBalance(0.0); 52 vc.add(c); 53 54 55 port.addNewCard(vc); 56 57 58 int cnt = 30000; 59 Vector<CardOperation> vco = new Vector<CardOperation>(); 60 CardOperation co; 61 for (int i = 0; i < cnt; i++) { 62 co = new CardOperation(); 63 switch (i%3){ 64 case 0: co.setCard("1"); co.setAmount(1); co.setOperationDate(dat);vco.add(co);break; 65 case 1: co.setCard("2"); co.setAmount(2); co.setOperationDate(dat);vco.add(co);break; 66 case 2: co.setCard("3"); co.setAmount(3); co.setOperationDate(dat);vco.add(co);break; 67 } 68 } 69 70 port.processOperation(vco); 71 72 printCard(port.getCard("1")); 73 printCard(port.getCard("2")); 74 printCard(port.getCard("3")); 75 76 77 78 } catch(Exception e) { 79 e.printStackTrace(); 80 } 81 } 82 public void printCard(Card card){ 83 System.out.println(card.getCardNumber()+"\t"+card.getPerson()+"\t"+ 84 card.getCreateDate()+"\t"+card.getBalance()); 85 } 86 }Листинг 12.4. Клиентский класс BillingClient
Сначала подключается соответствующая аннотация (пример 12.4). Именно с ее помощью (строка 12) мы указываем месторасположения WSDL -файла интересующего нас Web -сервиса, на основании анализа которого генерируются все вспомогательные классы. Затем подключаются классы пакета com.asw.ws.ex1.endpoint - все эти классы сгенерированы автоматически утилитой wsimport (еще раз повторимся: это не те классы, что мы написали при реализации Web -сервиса).
В main создается экземпляр нашего класса BillingClient и запускается его метод startTest (строка 18). Метод startTest первым делом создает клиентскую заглушку (строка 26), или proxy -класс, - класс, который реализует такие же методы, как и нужный нам Web -сервис, и который все их вызовы пересылает Web -серверу. И этот класс, и класс BillingService,который, собственно и создает клиентский proxy, созданы автоматически.
После того как клиентская заглушка создана, мы можем вызывать ее методы. Поскольку первый метод, который нам нужно вызвать - метод addNewCard,а он принимает в качестве параметра массив, для его вызова предстоит выполнить некоторые подготовительные действия. Сначала создается вектор, который мы будем передавать в качестве параметра (строка 28 )1В данном случае используется относительно новая возможность, появившаяся в версии 1.5. Это очень похоже на применение шаблона в C++ (производимый эффект - строгая типизация при работе с соответствующей структурой данных), за исключением того, что ответственность за проверку типов целиком лежит на компиляторе и не поддерживается на уровне виртуальной машины (по крайней мере, так обстоят дела на момент написания этих строк) . Затем последовательно создаются три экземпляра Card,поля которых заполняются нужными значениями. Эти карты добавляются в вектор. Вызов addNewCard (строка 55) передает созданные карты Web -сервису и заставляет его создать эти карты.
Похожим образом создаются 30000 операций с картами - по 10000 на каждую из созданных нами трех карт. Вызов processOperation (строка 70) передает созданный массив Web -серверу, а тот, в свою очередь, обработав их, изменяет балансы карт.
И наконец, вызовы метода getCard (строки 72-74) возвращают на клиента карты, которые распечатываются.
Компиляция и выполнение клиента
Так же как и для компиляции сервера, для компиляции клиента воспользуемся ant'ом. Соответствующая строка компиляции выглядит следующим образом (компиляция является целью по умолчанию):
asant
Вывод получим следующий
Buildfile: build.xml clean: javaee-home-test: init: prepare: [echo] Creating the required directories.... [mkdir] Created dir: H:\Java\jwstutorial20_new\examples\ jaxws\simpleclient\build generate-client: [wsimport] command line: wsimport H:\Java\AppServer\jdk\jre\bin\java.exe -classpath H:\Java\AppServer\lib\activation.jar; H:\Java\AppServer\lib\admin-cli.jar; H:\Java\AppServer\lib\appserv-admin.jar; H:\Java\AppServer\lib\appserv-ext.jar; H:\Java\AppServer\lib\jmxremote_optional.jar; H:\Java\AppServer\lib\appserv-cmp.jar; H:\Java\AppServer\lib\appserv-deployment-client.jar; H:\Java\AppServer\lib\appserv-jstl.jar; H:\Java\AppServer\lib\appserv-jwsacc.jar; H:\Java\AppServer\lib\appserv-launch.jar; H:\Java\AppServer\lib\appserv-rt.jar; H:\Java\AppServer\lib\appserv-tags.jar; H:\Java\AppServer\lib\appserv-upgrade.jar; H:\Java\AppServer\lib\appserv-ws.jar; H:\Java\AppServer\lib\com-sun-commons-launcher.jar; H:\Java\AppServer\lib\com-sun-commons-logging.jar; H:\Java\AppServer\lib\dbschema.jar; H:\Java\AppServer\lib\j2ee-svc.jar; H:\Java\AppServer\lib\j2ee.jar; H:\Java\AppServer\lib\javaee.jar; H:\Java\AppServer\lib\jhall.jar; H:\Java\AppServer\lib\jsf-impl.jar; H:\Java\AppServer\lib\mail.jar; H:\Java\AppServer\lib\sun-appserv-ant.jar; H:\Java\AppServer\lib\toplink-essentials-agent.jar; H:\Java\AppServer\lib\toplink-essentials.jar; H:\Java\AppServer\jdk\lib\tools.jar com.sun.tools.ws.WsImport -d H:\Java\jwstutorial20_new\examples\ jaxws\simpleclient\build -g -keep -s H:\Java\jwstutorial20_new\examples\jaxws\simpleclient\src -verbose http://localhost:8080/billingservice/billing?wsdl -p com.asw.ws.ex1.endpoint [wsimport] com\asw\ws\ex1\endpoint\AddMoney.java [wsimport] com\asw\ws\ex1\endpoint\AddMoneyResponse.java [wsimport] com\asw\ws\ex1\endpoint\AddNewCard.java [wsimport] com\asw\ws\ex1\endpoint\AddNewCardResponse.java [wsimport] com\asw\ws\ex1\endpoint\Billing.java [wsimport] com\asw\ws\ex1\endpoint\BillingService.java [wsimport] com\asw\ws\ex1\endpoint\Card.java [wsimport] com\asw\ws\ex1\endpoint\CardOperation.java [wsimport] com\asw\ws\ex1\endpoint\GetCard.java [wsimport] com\asw\ws\ex1\endpoint\GetCardResponse.java [wsimport] com\asw\ws\ex1\endpoint\ObjectFactory.java [wsimport] com\asw\ws\ex1\endpoint\ProcessOperation.java [wsimport] com\asw\ws\ex1\endpoint\ProcessOperationResponse.java [wsimport] com\asw\ws\ex1\endpoint\package-info.java [wsimport] com\asw\ws\ex1\endpoint\AddMoney.java [wsimport] com\asw\ws\ex1\endpoint\AddMoneyResponse.java [wsimport] com\asw\ws\ex1\endpoint\AddNewCard.java [wsimport] com\asw\ws\ex1\endpoint\AddNewCardResponse.java [wsimport] com\asw\ws\ex1\endpoint\Billing.java [wsimport] com\asw\ws\ex1\endpoint\BillingService.java [wsimport] com\asw\ws\ex1\endpoint\Card.java [wsimport] com\asw\ws\ex1\endpoint\CardOperation.java [wsimport] com\asw\ws\ex1\endpoint\GetCard.java [wsimport] com\asw\ws\ex1\endpoint\GetCardResponse.java [wsimport] com\asw\ws\ex1\endpoint\ObjectFactory.java [wsimport] com\asw\ws\ex1\endpoint\ProcessOperation.java [wsimport] com\asw\ws\ex1\endpoint\ProcessOperationResponse.java [wsimport] com\asw\ws\ex1\endpoint\package-info.java compile-client: [echo] Compiling the client source code ... [javac] Compiling 1 source file to H:\Java\ jwstutorial20_new\examples\jaxws\simpleclient\build prepare-dist: [echo] Creating the required directories ... [mkdir] Created dir: H:\Java\jwstutorial20_new\ examples\jaxws\simpleclient\dist package-client: [echo] Building the client JAR file ... [jar] Building jar: H:\Java\jwstutorial20_new\examples\jaxws\simpleclient\dist\client.jar build-client: build: BUILD SUCCESSFUL Total time: 16 seconds
В приведенном выводе можно увидеть работу утилиты wsimport по созданию вспомогательных файлов по WSDL Web -сервиса. Запустив клиента командой
asant run
видим, что все необходимые операции на Web -сервисе - создание карт, изменение балансов и запрос информации по картам - успешно выполнены:
Buildfile: build.xml run: appclient-command-common: [exec] 1 Piter 2006-11-05T00:00:00+03:00 10000.0 [exec] 2 Stefan 2006-11-05T00:00:00+03:00 20000.0 [exec] 3 Nataly 2006-11-05T00:00:00+03:00 30000.0 BUILD SUCCESSFUL Total time: 23 seconds