Опубликован: 10.10.2010 | Уровень: специалист | Доступ: платный
Лекция 12:

Web-сервисы. Примеры

< Лекция 11 || Лекция 12: 1234 || Лекция 13 >
Аннотация: В лекции приводится развернутый пример создания Web-сервиса и клиента к нему

Рабочий каталог расположен в Practice.

Теперь, после того как необходимые программные средства, такие как сервер приложений, инсталлированы, а необходимые сведения о технологии разработки получены, можно приступать к реализации нашего тестового примера с использованием технологии 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  }
Листинг 12.1. Реализация серверного класса Billing

В первых строчках импортируются необходимые классы, в том числе аннотации, уже знакомые по предыдущему примеру. Сам класс аннотирован как Web -сервис (аннотация @WebService),а его методы - как методы Web -сервиса (аннотация @WebMethod). Код самих методов обсуждать не имеет смысла - он в точности повторяет код примеров из предыдущего раздела. Обратим только внимание на тот факт, что в качестве передаваемых в методы и возвращаемых методами аргументов используются сложные типы данных - классы. Дело в том, что используемая нами технология позволяет передавать и возвращать в качестве параметров методов не только переменные базовых типов, но и объекты созданных пользователем классов - чем мы и воспользуемся. В данном случае определено два таких "транспортных" класса: Card,хранящий информацию о карте и использующийся в операциях типа заведения карты и просмотра атрибутов карты, и CardOperation,хранящий информацию об операции изменения баланса карты. Соответствующие определения классов будут приведены ниже.

Таким образом, у разрабатываемого Web -сервиса будут определены следующие методы:

  • addNewCard - метод, принимающий массив объектов Card и заносящий их в хэш-таблицу (пример метода, принимающего массив объектов пользовательского класса);
  • addMoney - метод, принимающий код карты и начисление и изменяющий баланс карты (пример метода, принимающего значения базовых типов данных);
  • processOperation - метод, принимающий массив объектов CardOperation и проводящий соответствующие операциям изменения баланса карт (пример метода, принимающего массив объектов пользовательского класса);
  • getCard - метод, возвращающий карту со всеми атрибутами по ее коду (пример метода, возвращающего объект пользовательского класса).

Следует отметить, что поскольку класс 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  }
Листинг 12.2. Транспортный класс Card

Транспортный класс 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  }
Листинг 12.3. Транспортный класс CardOperation

Следует обратить внимание на то, что у обоих транспортных классов добавлен конструктор по умолчанию - это одно из требований, накладываемых используемой технологией.

Компиляция и инсталляция в сервере приложений

Компиляция и развертывание приложения были подробно рассмотрены ранее, в предыдущем примере. Для компиляции этого примера использовалось инструментальное средство ant с разработанной системой скриптов.

Выполнив команду

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\helloservice\build
[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\helloservice\build -d 
H:\Java\jwstutorial20_new\examples\jaxws\helloservice\build -keep -s 
H:\Java\ jwstutorial20_new\examples\jaxws\helloservice\build -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) нам, к сожалению, не удастся, так как наши операции требуют передачи серверу объектов.

< Лекция 11 || Лекция 12: 1234 || Лекция 13 >
Алмаз Мурзабеков
Алмаз Мурзабеков
Прохожу курс "Построение распределенных систем на Java" в третьей лекции где описывается TCPServer вылетает эта ошибка
"Connection cannot be resolved to a type"


Java version 1.7.0_05
Александр Хвостов
Александр Хвостов
Россия
Максим Лютов
Максим Лютов
Россия, СПб, Политех, 2012