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