Рабочий каталог расположен в
Теперь, после того как необходимые программные средства, такие как сервер приложений, инсталлированы, а необходимые сведения о технологии разработки получены, можно приступать к реализации нашего тестового примера с использованием технологии Web -сервисов.
Начнем, как обычно, с реализации серверной части, т.е. собственно Web -сервиса.
Серверный класс Billing
Ниже представлен соответствующий серверный класс (пример 12.1).
1 package com.asw.ws.ex1.endpoint;
2
3 import javax.jws.WebMethod;
4 import javax.jws.WebService;
5 import java.util.Hashtable;
6
7
8 @WebService()
9 public class Billing {
10 private Hashtable hash;
11
12 public Billing(){
13 hash = new Hashtable();
14 }
15 @WebMethod()
16 public void addNewCard(Card[] cards) {
17 for (int i=0;i<cards.length;i++)
18 hash.put(cards[i].cardNumber, cards[i]);
19 }
20 @WebMethod()
21 public void addMoney(String card, double money) {
22 Card c = (Card)hash.get(card);
23 if (c==null) {
24 System.out.println("Bad Card number\n");
25 return;
26 };
27 c.balance+=money;
28 hash.put(card,c);
29 }
30 @WebMethod()
31 public void processOperation(CardOperation[] co) {
32 for (int i=0;i<co.length;i++){
33 Card c = (Card)hash.get(co[i].card);
34 if (c==null) {
35 System.out.println("Bad Card number\n");
36 };
37 c.balance+=co[i].amount;
38 hash.put(co[i].card,c);
39 }
40 }
41
42 @WebMethod()
43 public Card getCard(String card){
44 return (Card)hash.get(card);
45 }
46 }
В первых строчках импортируются необходимые классы, в том числе аннотации, уже знакомые по предыдущему примеру. Сам класс аннотирован как Web -сервис (аннотация @WebService),а его методы - как методы Web -сервиса (аннотация @WebMethod).
Код самих методов обсуждать не имеет смысла - он в точности повторяет код примеров из предыдущего раздела. Обратим только внимание на тот факт, что в качестве передаваемых в методы и возвращаемых методами аргументов используются
Таким образом, у разрабатываемого Web -сервиса будут определены следующие методы:
Следует отметить, что поскольку класс Billing должен удовлетворять требованиям, предъявляемым к Web -сервису, у него определен конструктор по умолчанию (без параметров).
Ниже приведены соответствующие транспортные классы (пример 12.2 и пример 12.3).
Транспортный класс Card
1 package com.asw.ws.ex1.endpoint;
2
3 import javax.jws.WebMethod;
4 import javax.jws.WebService;
5 import java.util.*;
6 public class Card {
7 public Card(){}
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 }
Транспортный класс CardOperation
1 package com.asw.ws.ex1.endpoint;
2 import java.util.*;
3 import java.io.*;
4
5 public class CardOperation {
6 public CardOperation(){}
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 }
Следует обратить внимание на то, что у обоих транспортных классов добавлен конструктор по умолчанию - это одно из требований, накладываемых используемой технологией.
Компиляция и инсталляция в сервере приложений
Компиляция и
Выполнив команду
asant build create-war deploy
получим следующий вывод:
Buildfile: build.xml javaee-home-test: init: prepare: [echo] Creating the required directories ... compile-service: [echo] Compiling the server-side source code ... [javac] Compiling 3 source files to H:\Java\jwstutorial20_new\examples\jaxws\helloserviceuild [javac] Note: H:\Java\jwstutorial20_new\examples\jaxws\helloservice\src\Billing.java uses unchecked or unsafe operations. [javac] Note: Recompile with -Xlint:unchecked for details. [wsgen] command line: wsimport -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-cmp.jar; H:\Java\AppServer\lib\appserv-deployment-client.jar; H:\Java\AppServer\lib\appserv-ext.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\jmxremote_optional.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; H:\Java\jwstutorial20_new\examples\jaxws\helloserviceuild -d H:\Java\jwstutorial20_new\examples\jaxws\helloserviceuild -keep -s H:\Java\ jwstutorial20_new\examples\jaxws\helloserviceuild -verbose com.asw.ws.ex1.endpoint.Billing [wsgen] Note: ap round: 1 [wsgen] [ProcessedMethods Class: com.asw.ws.ex1. endpoint.Billing] [wsgen] [should process method: addNewCard hasWebMethods: true ] [wsgen] [endpointReferencesInterface: false] [wsgen] [declaring class has WebSevice: true] [wsgen] [returning: true] [wsgen] [WrapperGen - method: addNewCard(com.asw.ws.ex1. endpoint.Card[])] [wsgen] [method.getDeclaringType(): com.asw.ws.ex1. endpoint.Billing] [wsgen] [requestWrapper: com.asw.ws.ex1.endpo-int.jaxws.AddNewCard] [wsgen] [should process method: addMoney hasWebMethods: true ] [wsgen] [endpointReferencesInterface: false] [wsgen] [declaring class has WebSevice: true] [wsgen] [returning: true] [wsgen] [WrapperGen - method: addMoney(java.lang.String,double)] [wsgen] [method.getDeclaringType(): com.asw.ws.ex1. endpoint.Billing] [wsgen] [requestWrapper: com.asw.ws.ex1.endpoint.jaxws. AddMoney] [wsgen] [should process method: processOperation hasWebMethods: true ] [wsgen] [endpointReferencesInterface: false] [wsgen] [declaring class has WebSevice: true] [wsgen] [returning: true] [wsgen] [WrapperGen - method: processOperation (com.asw.ws.ex1.endpoint.CardOperation[])] [wsgen] [method.getDeclaringType(): com.asw.ws.ex1.endpoint. Billing] [wsgen] [requestWrapper: com.asw.ws.ex1.endpoint. jaxws.ProcessOperation] [wsgen] [should process method: getCard hasWebMethods: true ] [wsgen] [endpointReferencesInterface: false] [wsgen] [declaring class has WebSevice: true] [wsgen] [returning: true] [wsgen] [WrapperGen - method: getCard(java.lang.String)] [wsgen] [method.getDeclaringType(): com.asw.ws.ex1.endpoint. Billing] [wsgen] [requestWrapper: com.asw.ws.ex1.endpoint. jaxws.GetCard] [wsgen] [ProcessedMethods Class: java.lang.Object] [wsgen] com\asw\ws\ex1\endpoint\jaxws\AddMoney.java [wsgen] com\asw\ws\ex1\endpoint\jaxws\AddMoneyResponse.java [wsgen] com\asw\ws\ex1\endpoint\jaxws\AddNewCard.java [wsgen] com\asw\ws\ex1\endpoint\jaxws\AddNewCardResponse.java [wsgen] com\asw\ws\ex1\endpoint\jaxws\GetCard.java [wsgen] com\asw\ws\ex1\endpoint\jaxws\GetCardResponse.java [wsgen] com\asw\ws\ex1\endpoint\jaxws\ProcessOperation.java [wsgen] com\asw\ws\ex1\endpoint\jaxws\ProcessOperationResponse.java [wsgen] Note: ap round: 2 [wsgen] [completing model for endpoint: com.asw.ws.ex1. endpoint.Billing] [wsgen] [ProcessedMethods Class: com.asw.ws.ex1.endpoint. Billing] [wsgen] [should process method: addNewCard hasWebMethods: true ] [wsgen] [endpointReferencesInterface: false] [wsgen] [declaring class has WebSevice: true] [wsgen] [returning: true] [wsgen] [WebServiceReferenceCollector - method: addNewCard(com.asw.ws.ex1.endpoint.Card[])] [wsgen] [should process method: addMoney hasWebMethods: true ] [wsgen] [endpointReferencesInterface: false] [wsgen] [declaring class has WebSevice: true] [wsgen] [returning: true] [wsgen] [WebServiceReferenceCollector - method: addMoney (java.lang.String,double)] [wsgen] [should process method: processOperation hasWeb-Methods: true ] [wsgen] [endpointReferencesInterface: false] [wsgen] [declaring class has WebSevice: true] [wsgen] [returning: true] [wsgen] [WebServiceReferenceCollector - method: processOperation(com.asw.ws.ex1.endpoint.CardOperation[])] [wsgen] [should process method: getCard hasWebMethods: true ] [wsgen] [endpointReferencesInterface: false] [wsgen] [declaring class has WebSevice: true] [wsgen] [returning: true] [wsgen] [WebServiceReferenceCollector - method: get-Card(java.lang.String)] [wsgen] [ProcessedMethods Class: java.lang.Object] build-service: build: prepare-assemble: [echo] Creating the assemble directory ... [mkdir] Created dir: H:\Java\jwstutorial20_new\examples\ jaxws\helloservice\assemble [mkdir] Created dir: H:\Java\jwstutorial20_new\examples\ jaxws\helloservice\assemble\war create-war: [echo] Creating the WAR ... [war] Building war: H:\Java\jwstutorial20_new\examples\ jaxws\helloservice\assemble\war\billing-jaxws.war deploy: admin_command_common: [echo] Doing admin task deploy assemble/war/ billing-jaxws.war [sun-appserv-admin] Executing: deploy --port 4848 --host localhost --passwordfile "H:\Java\jwstutorial20_new\examples\ common\admin-password.txt" --user admin assemble/war/ billing-jaxws.war [sun-appserv-admin] Command deploy executed successfully. BUILD SUCCESSFUL Total time: 22 seconds
Одной командой мы сразу откомпилировали, упаковали в необходимую для Web -приложения структуру и разместили на сервере приложений наш пример. Следует обратить внимание на количество автоматически сгенерированных утилитой wsgen классов - на каждый метод Web -сервиса их сгенерировано по 2.
Теперь можно воспользоваться административной консолью, чтобы убедиться, что наш Web -сервис успешно инсталлирован (рис. 12.1).
(рис 12.1) Проверка инсталляции серверного класса
(рис 12.2) Тестовая страницаВоспользоваться автоматически построенной сервером тестовой страницей (рис. 12.2) нам, к сожалению, не удастся, так как наши операции требуют передачи серверу объектов.
Клиентский класс BillingClient
При реализации клиента первая проблема состоит в том, что вызываемые методы Web -сервиса принимают аргументы - объекты. Вторая проблема состоит в том, что некоторые из этих методов принимают
Первая проблема возникает из-за того, что на самом деле клиентское приложение не получает доступа к "настоящим" классам сервера - т.е. клиент не имеет доступа к классам com.asw.ws.ex1.endpoint.Card или com.asw.ws.ex1.endpoint.CardOperation,рассмотренным в предыдущем разделе и реализованным на сервере.
Вместо этого утилитой wsimport на основании анализа файла генерируются другие классы. Они тоже располагаются в пакете 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). Именно с ее помощью (строка 12) мы указываем месторасположения -файла интересующего нас Web -сервиса, на основании анализа которого генерируются все вспомогательные классы. Затем подключаются классы пакета com.asw.ws.ex1.endpoint - все эти классы сгенерированы автоматически утилитой wsimport (еще раз повторимся: это не те классы, что мы написали при реализации Web -сервиса).
В main создается экземпляр нашего класса BillingClient и запускается его метод startTest (строка 18). Метод startTest первым делом создает клиентскую заглушку (строка 26), или proxy -класс, - класс, который реализует такие же методы, как и нужный нам Web -сервис, и который все их вызовы пересылает Web -серверу. И этот класс, и класс BillingService,который, собственно и создает клиентский proxy, созданы автоматически.
После того как клиентская заглушка создана, мы можем вызывать ее методы. Поскольку первый метод, который нам нужно вызвать - метод addNewCard,а он принимает в качестве параметра массив, для его вызова предстоит выполнить некоторые подготовительные действия. Сначала создается вектор, который мы будем передавать в качестве параметра (строка 28 C++ (производимый эффект - 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\simpleclientuild 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\simpleclientuild -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\endpointCard.java [wsimport] com\asw\ws\ex1\endpointCardOperation.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\endpointCard.java [wsimport] com\asw\ws\ex1\endpointCardOperation.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\simpleclientuild 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 по созданию вспомогательных файлов по -сервиса. Запустив клиента командой
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
Одна из основных идей, лежащих в основе технологии Web -серви-сов, состоит в независимости разрабатываемых на ее основе приложений от используемой платформы. Поэтому, в качестве дополнения к предыдущему примеру, мы реализуем второго клиента для того же самого Web -сервиса, но на основе совершенно другой технологии. В качестве клиента мы будем использовать стандартное Web -приложение, состоящее из набора HTML -страниц с небольшими вкраплениями -кода.
Допустим, для автоматизируемой нами сети ресторанов нужно создать Web -сайт, на котором клиенты могли бы просмотреть текущий баланс своих карт, а сотрудники могли бы выполнить некоторые действия с системой - например, создать новую карту. Соответствующий код, реализующий такую функциональность, представлен ниже.
Поскольку мы не ставим своей целью рассмотреть в подробностях процесс Web -программирования, остановимся только на основных деталях. По сути, наше приложение состоит из нескольких -страниц. Поскольку мы разделили страницы, содержащие операции запроса баланса и создания новой карты, их получилось четыре.
Для того чтобы -код смог работать с Web -сервисом, необходимо, как и в случае с предыдущим клиентом, сгенерировать вспомогательные классы с помощью утилиты wsimport и разместить их в соответствующей папке ( classes ) Web -приложения.
Итак, реализуем две -страницы, которые содержат формы для ввода параметров: одна для метода просмотра баланса (вводится один параметр - номер просматриваемой карты), вторая для операции заведения новой карты (вводится два параметра - номер карты и персона). Еще две -страницы загружаются первыми при нажатии соответствующих кнопок в форме и содержат код, вызывающий методы Web -сервиса.
Страница ShowBalance.jsp
Содержит форму параметров для вызова метода getCard Web -сервиса (пример 12.5). Вызывает showbalanceresponse..
<html>
<head><title>BillingService</title></head>
<h2>Enter card number</h2>
<form method="get">
<input type="text" name="cardnumber" size="25">
<p></p>
<input type="submit" value="Submit">
<input type="reset" value="Reset">
</form>
<%
String cardnumber = request.getParameter("cardnumber");
if ( cardnumber != null cardnumber.length() > 0 ) {
%>
<%@include file="showbalanceresponse.jsp" %>
<%
}
%>
</body>
</html>
Страница showbalanceresponse.jsp
Содержит код для обращения к Web -сервису (пример 12.5), для чего подключает классы com.asw.ws.ex1.endpoint.BillingService, com.asw.ws.ex1. endpoint.Billing, com.asw.ws.ex1.endpoint.Card,которые были автоматически сгенерированы утилитой wsimport на основании анализа файла Web -сервиса. Эти классы должны располагаться в папке classes Web -приложения.
Вызывает метод Web -сервиса getCard, передавая ему в качестве аргумента значение, введенное в форме. Поля возвращенного объекта выводятся на странице.
<%@ page import="com.asw.ws.ex1.endpoint.BillingService,
com.asw.ws.ex1.endpoint.Billing, com.asw.ws.ex1.endpoint.Card" %>
<%
Card resp = null;
try {
Billing billing = new BillingService().getBillingPort();
resp = billing.getCard(request.getParameter("cardnumber"));
} catch (Exception ex) { resp = new Card();
}
%>
<h2>
<font color="black">
<%=resp.getPerson()+"\t"+resp.getBalance()%>
</font></h2>
Страница AddCard.jsp
Содержит форму параметров для вызова метода addNewCard Web -сервиса (пример 12.7) (в данном случае страница предназначена для создания одной карты за один раз, в качестве параметров вводятся номер карты и персона). Вызывает addcardresponse..
<html>
<head><title>BillingService</title></head>
<h2>Enter card number</h2>
<form method="get">
<input type="text" name="cardnumber"
size="25">
<input type="text" name="person"
size="25">
<p></p>
<input type="submit" value="Submit">
<input type="reset" value="Reset">
</form>
<%
String cardnumber = request.getParameter("cardnumber");
String person = request.getParameter("person");
if ( cardnumber != null cardnumber.length() > 0
person != null person.length() > 0) {
%>
<%@include file="addcardresponse.jsp" %>
<%
}
%>
</body>
</html>
Страница addcardresponse.jsp
Содержит код для обращения к Web -сервису (пример 12.8), для чего подключает классы com.asw.ws.ex1.endpoint.BillingService, com.asw.ws.ex1. endpoint.Billing, com.asw.ws.ex1.endpoint.Card,которые были автоматически сгенерированы утилитой wsimport на основании анализа файла Web -сервиса.
Эти классы должны располагаться в папке classes Web -приложения. Вызывает метод Web -сервиса addNewCard,для чего создает объект класса Card и устанавливает его поля значениями, введенными в форме. Созданный объект добавляется в вектор, который передается в качестве аргумента методу addNewCard.
<%@ page import="com.asw.ws.ex1.endpoint.BillingService,
com.asw.ws.ex1.endpoint.Billing, com.asw.ws.ex1.endpoint.Card" %>
<%
Card card = new Card();
try {
Billing billing = new BillingService().getBillingPort();
String _cardnumber = request.getParameter("cardnumber");
String _person = request.getParameter("person");
card.setPerson(_person);
card.setCardNumber(_cardnumber);
java.util.Vector<Card> v = new java.util.Vector<Card>();
v.add(card);
billing.addNewCard(v);
} catch (Exception ex) {
}
%>
<h2> <font color="black">
<%=card.getPerson()+"\t"+card.getBalance()%>
</font>
</h2>
Структура каталога приложения
Каталог Web -приложения будет иметь следующую структуру:
.\AddCard.jsp .\addcardresponse.jsp .\ShowBalance.jsp .\showbalanceresponse.jsp .\META-INF\MANIFEST.MF .\WEB-INF\classes .\WEB-INF\sun-web.xml .\WEB-INF\web.xml .\WEB-INF\classes\com\asw\ws\ex1\endpoint\AddMoney.class .\WEB-INF\classes\com\asw\ws\ex1\endpoint\AddMoneyResponse.class .\WEB-INF\classes\com\asw\ws\ex1\endpoint\AddNewCard.class .\WEB-INF\classes\com\asw\ws\ex1\endpoint\AddNewCardResponse.class .\WEB-INF\classes\com\asw\ws\ex1\endpoint\Billing.class .\WEB-INF\classes\com\asw\ws\ex1\endpoint\BillingService.class .\WEB-INF\classes\com\asw\ws\ex1\endpointCard.class .\WEB-INF\classes\com\asw\ws\ex1\endpointCardOperation.class .\WEB-INF\classes\com\asw\ws\ex1\endpoint\GetCard.class .\WEB-INF\classes\com\asw\ws\ex1\endpoint\GetCardResponse.class .\WEB-INF\classes\com\asw\ws\ex1\endpoint\ObjectFactory.class .\WEB-INF\classes\com\asw\ws\ex1\endpoint\package-info.class .\WEB-INF\classes\com\asw\ws\ex1\endpoint\ProcessOperation.class .\WEB-INF\classes\com\asw\ws\ex1\endpoint\ProcessOperationResponse.class
В корне приложения лежат разработанные нами -страницы, в папке WEB-INF - файлы, содержащие необходимые для развертывания
(рис 12.3) Страница ShowBalance.jsp
(рис 12.4) Результат запроса информации по карте
(рис 12.5) Страница AddCard.jsp
(рис 12.6) Результат операции по вводу новой картына сервере и настройки нашего приложения параметры, а в папке .\WEB-INF\ classes - сгенерированные утилитой wsimport классы.
После развертывания приложения на сервере, обратившись по адресу http://localhost:8080/webclient/ShowBalance.jsp ( webclient - корневой раздел нашего приложения, определен в файле sun-web.xml ), мы увидим следующую страницу (рис. 12.3).
Введя номер карты и нажав кнопку Submit,мы получим информацию по карте с введенным номером (рис 12.4). Поскольку этот пример выполняется после того, как первый клиент выполнил 30000 операций над картами, значение баланса карт будет довольно велико.
(рис 12.7) Результат запроса информации по вновь введенной картеДля того чтобы создать новую карту, нужно загрузить другую страницу - http://localhost:8080/webclient/AddCard.jsp (рис 12.5).
Заполнив поля и нажав кнопку Submit, мы создадим новую карту в системе (рис 12.6), в чем можно убедиться, просмотрев информацию по ней с помощью первой страницы (рис 12.7).
Рабочий каталог расположен в
Теперь, после того как необходимые программные средства, такие как сервер приложений, инсталлированы, а необходимые сведения о технологии разработки получены, можно приступать к реализации нашего тестового примера с использованием технологии Web -сервисов.
Начнем, как обычно, с реализации серверной части, т.е. собственно Web -сервиса.
Серверный класс Billing
Ниже представлен соответствующий серверный класс (пример 12.1).
1 package com.asw.ws.ex1.endpoint;
2
3 import javax.jws.WebMethod;
4 import javax.jws.WebService;
5 import java.util.Hashtable;
6
7
8 @WebService()
9 public class Billing {
10 private Hashtable hash;
11
12 public Billing(){
13 hash = new Hashtable();
14 }
15 @WebMethod()
16 public void addNewCard(Card[] cards) {
17 for (int i=0;i<cards.length;i++)
18 hash.put(cards[i].cardNumber, cards[i]);
19 }
20 @WebMethod()
21 public void addMoney(String card, double money) {
22 Card c = (Card)hash.get(card);
23 if (c==null) {
24 System.out.println("Bad Card number\n");
25 return;
26 };
27 c.balance+=money;
28 hash.put(card,c);
29 }
30 @WebMethod()
31 public void processOperation(CardOperation[] co) {
32 for (int i=0;i<co.length;i++){
33 Card c = (Card)hash.get(co[i].card);
34 if (c==null) {
35 System.out.println("Bad Card number\n");
36 };
37 c.balance+=co[i].amount;
38 hash.put(co[i].card,c);
39 }
40 }
41
42 @WebMethod()
43 public Card getCard(String card){
44 return (Card)hash.get(card);
45 }
46 }
В первых строчках импортируются необходимые классы, в том числе аннотации, уже знакомые по предыдущему примеру. Сам класс аннотирован как Web -сервис (аннотация @WebService),а его методы - как методы Web -сервиса (аннотация @WebMethod).
Код самих методов обсуждать не имеет смысла - он в точности повторяет код примеров из предыдущего раздела. Обратим только внимание на тот факт, что в качестве передаваемых в методы и возвращаемых методами аргументов используются
Таким образом, у разрабатываемого Web -сервиса будут определены следующие методы:
Следует отметить, что поскольку класс Billing должен удовлетворять требованиям, предъявляемым к Web -сервису, у него определен конструктор по умолчанию (без параметров).
Ниже приведены соответствующие транспортные классы (пример 12.2 и пример 12.3).
Транспортный класс Card
1 package com.asw.ws.ex1.endpoint;
2
3 import javax.jws.WebMethod;
4 import javax.jws.WebService;
5 import java.util.*;
6 public class Card {
7 public Card(){}
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 }
Транспортный класс CardOperation
1 package com.asw.ws.ex1.endpoint;
2 import java.util.*;
3 import java.io.*;
4
5 public class CardOperation {
6 public CardOperation(){}
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 }
Следует обратить внимание на то, что у обоих транспортных классов добавлен конструктор по умолчанию - это одно из требований, накладываемых используемой технологией.
Компиляция и инсталляция в сервере приложений
Компиляция и
Выполнив команду
asant build create-war deploy
получим следующий вывод:
Buildfile: build.xml javaee-home-test: init: prepare: [echo] Creating the required directories ... compile-service: [echo] Compiling the server-side source code ... [javac] Compiling 3 source files to H:\Java\jwstutorial20_new\examples\jaxws\helloserviceuild [javac] Note: H:\Java\jwstutorial20_new\examples\jaxws\helloservice\src\Billing.java uses unchecked or unsafe operations. [javac] Note: Recompile with -Xlint:unchecked for details. [wsgen] command line: wsimport -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-cmp.jar; H:\Java\AppServer\lib\appserv-deployment-client.jar; H:\Java\AppServer\lib\appserv-ext.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\jmxremote_optional.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; H:\Java\jwstutorial20_new\examples\jaxws\helloserviceuild -d H:\Java\jwstutorial20_new\examples\jaxws\helloserviceuild -keep -s H:\Java\ jwstutorial20_new\examples\jaxws\helloserviceuild -verbose com.asw.ws.ex1.endpoint.Billing [wsgen] Note: ap round: 1 [wsgen] [ProcessedMethods Class: com.asw.ws.ex1. endpoint.Billing] [wsgen] [should process method: addNewCard hasWebMethods: true ] [wsgen] [endpointReferencesInterface: false] [wsgen] [declaring class has WebSevice: true] [wsgen] [returning: true] [wsgen] [WrapperGen - method: addNewCard(com.asw.ws.ex1. endpoint.Card[])] [wsgen] [method.getDeclaringType(): com.asw.ws.ex1. endpoint.Billing] [wsgen] [requestWrapper: com.asw.ws.ex1.endpo-int.jaxws.AddNewCard] [wsgen] [should process method: addMoney hasWebMethods: true ] [wsgen] [endpointReferencesInterface: false] [wsgen] [declaring class has WebSevice: true] [wsgen] [returning: true] [wsgen] [WrapperGen - method: addMoney(java.lang.String,double)] [wsgen] [method.getDeclaringType(): com.asw.ws.ex1. endpoint.Billing] [wsgen] [requestWrapper: com.asw.ws.ex1.endpoint.jaxws. AddMoney] [wsgen] [should process method: processOperation hasWebMethods: true ] [wsgen] [endpointReferencesInterface: false] [wsgen] [declaring class has WebSevice: true] [wsgen] [returning: true] [wsgen] [WrapperGen - method: processOperation (com.asw.ws.ex1.endpoint.CardOperation[])] [wsgen] [method.getDeclaringType(): com.asw.ws.ex1.endpoint. Billing] [wsgen] [requestWrapper: com.asw.ws.ex1.endpoint. jaxws.ProcessOperation] [wsgen] [should process method: getCard hasWebMethods: true ] [wsgen] [endpointReferencesInterface: false] [wsgen] [declaring class has WebSevice: true] [wsgen] [returning: true] [wsgen] [WrapperGen - method: getCard(java.lang.String)] [wsgen] [method.getDeclaringType(): com.asw.ws.ex1.endpoint. Billing] [wsgen] [requestWrapper: com.asw.ws.ex1.endpoint. jaxws.GetCard] [wsgen] [ProcessedMethods Class: java.lang.Object] [wsgen] com\asw\ws\ex1\endpoint\jaxws\AddMoney.java [wsgen] com\asw\ws\ex1\endpoint\jaxws\AddMoneyResponse.java [wsgen] com\asw\ws\ex1\endpoint\jaxws\AddNewCard.java [wsgen] com\asw\ws\ex1\endpoint\jaxws\AddNewCardResponse.java [wsgen] com\asw\ws\ex1\endpoint\jaxws\GetCard.java [wsgen] com\asw\ws\ex1\endpoint\jaxws\GetCardResponse.java [wsgen] com\asw\ws\ex1\endpoint\jaxws\ProcessOperation.java [wsgen] com\asw\ws\ex1\endpoint\jaxws\ProcessOperationResponse.java [wsgen] Note: ap round: 2 [wsgen] [completing model for endpoint: com.asw.ws.ex1. endpoint.Billing] [wsgen] [ProcessedMethods Class: com.asw.ws.ex1.endpoint. Billing] [wsgen] [should process method: addNewCard hasWebMethods: true ] [wsgen] [endpointReferencesInterface: false] [wsgen] [declaring class has WebSevice: true] [wsgen] [returning: true] [wsgen] [WebServiceReferenceCollector - method: addNewCard(com.asw.ws.ex1.endpoint.Card[])] [wsgen] [should process method: addMoney hasWebMethods: true ] [wsgen] [endpointReferencesInterface: false] [wsgen] [declaring class has WebSevice: true] [wsgen] [returning: true] [wsgen] [WebServiceReferenceCollector - method: addMoney (java.lang.String,double)] [wsgen] [should process method: processOperation hasWeb-Methods: true ] [wsgen] [endpointReferencesInterface: false] [wsgen] [declaring class has WebSevice: true] [wsgen] [returning: true] [wsgen] [WebServiceReferenceCollector - method: processOperation(com.asw.ws.ex1.endpoint.CardOperation[])] [wsgen] [should process method: getCard hasWebMethods: true ] [wsgen] [endpointReferencesInterface: false] [wsgen] [declaring class has WebSevice: true] [wsgen] [returning: true] [wsgen] [WebServiceReferenceCollector - method: get-Card(java.lang.String)] [wsgen] [ProcessedMethods Class: java.lang.Object] build-service: build: prepare-assemble: [echo] Creating the assemble directory ... [mkdir] Created dir: H:\Java\jwstutorial20_new\examples\ jaxws\helloservice\assemble [mkdir] Created dir: H:\Java\jwstutorial20_new\examples\ jaxws\helloservice\assemble\war create-war: [echo] Creating the WAR ... [war] Building war: H:\Java\jwstutorial20_new\examples\ jaxws\helloservice\assemble\war\billing-jaxws.war deploy: admin_command_common: [echo] Doing admin task deploy assemble/war/ billing-jaxws.war [sun-appserv-admin] Executing: deploy --port 4848 --host localhost --passwordfile "H:\Java\jwstutorial20_new\examples\ common\admin-password.txt" --user admin assemble/war/ billing-jaxws.war [sun-appserv-admin] Command deploy executed successfully. BUILD SUCCESSFUL Total time: 22 seconds
Одной командой мы сразу откомпилировали, упаковали в необходимую для Web -приложения структуру и разместили на сервере приложений наш пример. Следует обратить внимание на количество автоматически сгенерированных утилитой wsgen классов - на каждый метод Web -сервиса их сгенерировано по 2.
Теперь можно воспользоваться административной консолью, чтобы убедиться, что наш Web -сервис успешно инсталлирован (рис. 12.1).
(рис 12.1) Проверка инсталляции серверного класса
(рис 12.2) Тестовая страницаВоспользоваться автоматически построенной сервером тестовой страницей (рис. 12.2) нам, к сожалению, не удастся, так как наши операции требуют передачи серверу объектов.
Клиентский класс BillingClient
При реализации клиента первая проблема состоит в том, что вызываемые методы Web -сервиса принимают аргументы - объекты. Вторая проблема состоит в том, что некоторые из этих методов принимают
Первая проблема возникает из-за того, что на самом деле клиентское приложение не получает доступа к "настоящим" классам сервера - т.е. клиент не имеет доступа к классам com.asw.ws.ex1.endpoint.Card или com.asw.ws.ex1.endpoint.CardOperation,рассмотренным в предыдущем разделе и реализованным на сервере.
Вместо этого утилитой wsimport на основании анализа файла генерируются другие классы. Они тоже располагаются в пакете 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). Именно с ее помощью (строка 12) мы указываем месторасположения -файла интересующего нас Web -сервиса, на основании анализа которого генерируются все вспомогательные классы. Затем подключаются классы пакета com.asw.ws.ex1.endpoint - все эти классы сгенерированы автоматически утилитой wsimport (еще раз повторимся: это не те классы, что мы написали при реализации Web -сервиса).
В main создается экземпляр нашего класса BillingClient и запускается его метод startTest (строка 18). Метод startTest первым делом создает клиентскую заглушку (строка 26), или proxy -класс, - класс, который реализует такие же методы, как и нужный нам Web -сервис, и который все их вызовы пересылает Web -серверу. И этот класс, и класс BillingService,который, собственно и создает клиентский proxy, созданы автоматически.
После того как клиентская заглушка создана, мы можем вызывать ее методы. Поскольку первый метод, который нам нужно вызвать - метод addNewCard,а он принимает в качестве параметра массив, для его вызова предстоит выполнить некоторые подготовительные действия. Сначала создается вектор, который мы будем передавать в качестве параметра (строка 28 C++ (производимый эффект - 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\simpleclientuild 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\simpleclientuild -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\endpointCard.java [wsimport] com\asw\ws\ex1\endpointCardOperation.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\endpointCard.java [wsimport] com\asw\ws\ex1\endpointCardOperation.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\simpleclientuild 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 по созданию вспомогательных файлов по -сервиса. Запустив клиента командой
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
Одна из основных идей, лежащих в основе технологии Web -серви-сов, состоит в независимости разрабатываемых на ее основе приложений от используемой платформы. Поэтому, в качестве дополнения к предыдущему примеру, мы реализуем второго клиента для того же самого Web -сервиса, но на основе совершенно другой технологии. В качестве клиента мы будем использовать стандартное Web -приложение, состоящее из набора HTML -страниц с небольшими вкраплениями -кода.
Допустим, для автоматизируемой нами сети ресторанов нужно создать Web -сайт, на котором клиенты могли бы просмотреть текущий баланс своих карт, а сотрудники могли бы выполнить некоторые действия с системой - например, создать новую карту. Соответствующий код, реализующий такую функциональность, представлен ниже.
Поскольку мы не ставим своей целью рассмотреть в подробностях процесс Web -программирования, остановимся только на основных деталях. По сути, наше приложение состоит из нескольких -страниц. Поскольку мы разделили страницы, содержащие операции запроса баланса и создания новой карты, их получилось четыре.
Для того чтобы -код смог работать с Web -сервисом, необходимо, как и в случае с предыдущим клиентом, сгенерировать вспомогательные классы с помощью утилиты wsimport и разместить их в соответствующей папке ( classes ) Web -приложения.
Итак, реализуем две -страницы, которые содержат формы для ввода параметров: одна для метода просмотра баланса (вводится один параметр - номер просматриваемой карты), вторая для операции заведения новой карты (вводится два параметра - номер карты и персона). Еще две -страницы загружаются первыми при нажатии соответствующих кнопок в форме и содержат код, вызывающий методы Web -сервиса.
Страница ShowBalance.jsp
Содержит форму параметров для вызова метода getCard Web -сервиса (пример 12.5). Вызывает showbalanceresponse..
<html>
<head><title>BillingService</title></head>
<h2>Enter card number</h2>
<form method="get">
<input type="text" name="cardnumber" size="25">
<p></p>
<input type="submit" value="Submit">
<input type="reset" value="Reset">
</form>
<%
String cardnumber = request.getParameter("cardnumber");
if ( cardnumber != null cardnumber.length() > 0 ) {
%>
<%@include file="showbalanceresponse.jsp" %>
<%
}
%>
</body>
</html>
Страница showbalanceresponse.jsp
Содержит код для обращения к Web -сервису (пример 12.5), для чего подключает классы com.asw.ws.ex1.endpoint.BillingService, com.asw.ws.ex1. endpoint.Billing, com.asw.ws.ex1.endpoint.Card,которые были автоматически сгенерированы утилитой wsimport на основании анализа файла Web -сервиса. Эти классы должны располагаться в папке classes Web -приложения.
Вызывает метод Web -сервиса getCard, передавая ему в качестве аргумента значение, введенное в форме. Поля возвращенного объекта выводятся на странице.
<%@ page import="com.asw.ws.ex1.endpoint.BillingService,
com.asw.ws.ex1.endpoint.Billing, com.asw.ws.ex1.endpoint.Card" %>
<%
Card resp = null;
try {
Billing billing = new BillingService().getBillingPort();
resp = billing.getCard(request.getParameter("cardnumber"));
} catch (Exception ex) { resp = new Card();
}
%>
<h2>
<font color="black">
<%=resp.getPerson()+"\t"+resp.getBalance()%>
</font></h2>
Страница AddCard.jsp
Содержит форму параметров для вызова метода addNewCard Web -сервиса (пример 12.7) (в данном случае страница предназначена для создания одной карты за один раз, в качестве параметров вводятся номер карты и персона). Вызывает addcardresponse..
<html>
<head><title>BillingService</title></head>
<h2>Enter card number</h2>
<form method="get">
<input type="text" name="cardnumber"
size="25">
<input type="text" name="person"
size="25">
<p></p>
<input type="submit" value="Submit">
<input type="reset" value="Reset">
</form>
<%
String cardnumber = request.getParameter("cardnumber");
String person = request.getParameter("person");
if ( cardnumber != null cardnumber.length() > 0
person != null person.length() > 0) {
%>
<%@include file="addcardresponse.jsp" %>
<%
}
%>
</body>
</html>
Страница addcardresponse.jsp
Содержит код для обращения к Web -сервису (пример 12.8), для чего подключает классы com.asw.ws.ex1.endpoint.BillingService, com.asw.ws.ex1. endpoint.Billing, com.asw.ws.ex1.endpoint.Card,которые были автоматически сгенерированы утилитой wsimport на основании анализа файла Web -сервиса.
Эти классы должны располагаться в папке classes Web -приложения. Вызывает метод Web -сервиса addNewCard,для чего создает объект класса Card и устанавливает его поля значениями, введенными в форме. Созданный объект добавляется в вектор, который передается в качестве аргумента методу addNewCard.
<%@ page import="com.asw.ws.ex1.endpoint.BillingService,
com.asw.ws.ex1.endpoint.Billing, com.asw.ws.ex1.endpoint.Card" %>
<%
Card card = new Card();
try {
Billing billing = new BillingService().getBillingPort();
String _cardnumber = request.getParameter("cardnumber");
String _person = request.getParameter("person");
card.setPerson(_person);
card.setCardNumber(_cardnumber);
java.util.Vector<Card> v = new java.util.Vector<Card>();
v.add(card);
billing.addNewCard(v);
} catch (Exception ex) {
}
%>
<h2> <font color="black">
<%=card.getPerson()+"\t"+card.getBalance()%>
</font>
</h2>
Структура каталога приложения
Каталог Web -приложения будет иметь следующую структуру:
.\AddCard.jsp .\addcardresponse.jsp .\ShowBalance.jsp .\showbalanceresponse.jsp .\META-INF\MANIFEST.MF .\WEB-INF\classes .\WEB-INF\sun-web.xml .\WEB-INF\web.xml .\WEB-INF\classes\com\asw\ws\ex1\endpoint\AddMoney.class .\WEB-INF\classes\com\asw\ws\ex1\endpoint\AddMoneyResponse.class .\WEB-INF\classes\com\asw\ws\ex1\endpoint\AddNewCard.class .\WEB-INF\classes\com\asw\ws\ex1\endpoint\AddNewCardResponse.class .\WEB-INF\classes\com\asw\ws\ex1\endpoint\Billing.class .\WEB-INF\classes\com\asw\ws\ex1\endpoint\BillingService.class .\WEB-INF\classes\com\asw\ws\ex1\endpointCard.class .\WEB-INF\classes\com\asw\ws\ex1\endpointCardOperation.class .\WEB-INF\classes\com\asw\ws\ex1\endpoint\GetCard.class .\WEB-INF\classes\com\asw\ws\ex1\endpoint\GetCardResponse.class .\WEB-INF\classes\com\asw\ws\ex1\endpoint\ObjectFactory.class .\WEB-INF\classes\com\asw\ws\ex1\endpoint\package-info.class .\WEB-INF\classes\com\asw\ws\ex1\endpoint\ProcessOperation.class .\WEB-INF\classes\com\asw\ws\ex1\endpoint\ProcessOperationResponse.class
В корне приложения лежат разработанные нами -страницы, в папке WEB-INF - файлы, содержащие необходимые для развертывания
(рис 12.3) Страница ShowBalance.jsp
(рис 12.4) Результат запроса информации по карте
(рис 12.5) Страница AddCard.jsp
(рис 12.6) Результат операции по вводу новой картына сервере и настройки нашего приложения параметры, а в папке .\WEB-INF\ classes - сгенерированные утилитой wsimport классы.
После развертывания приложения на сервере, обратившись по адресу http://localhost:8080/webclient/ShowBalance.jsp ( webclient - корневой раздел нашего приложения, определен в файле sun-web.xml ), мы увидим следующую страницу (рис. 12.3).
Введя номер карты и нажав кнопку Submit,мы получим информацию по карте с введенным номером (рис 12.4). Поскольку этот пример выполняется после того, как первый клиент выполнил 30000 операций над картами, значение баланса карт будет довольно велико.
(рис 12.7) Результат запроса информации по вновь введенной картеДля того чтобы создать новую карту, нужно загрузить другую страницу - http://localhost:8080/webclient/AddCard.jsp (рис 12.5).
Заполнив поля и нажав кнопку Submit, мы создадим новую карту в системе (рис 12.6), в чем можно убедиться, просмотрев информацию по ней с помощью первой страницы (рис 12.7).
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.