Skip to content

8. Версія 4 — клієнт/сервер у архітектурі веб-сервісів

У цій новій версії додаток [Pam] працюватиме в режимі «клієнт/сервер» в архітектурі веб-сервісів. Повернемося до архітектури попереднього додатка:

Як показано вище, комунікаційний рівень [C, RMI, S] забезпечував прозору взаємодію між клієнтом [ui] та віддаленим рівнем [metier]. Ми будемо використовувати аналогічну архітектуру, де комунікаційний рівень [C, RMI, S] буде замінено на рівень [C, HTTP / SOAP, S]:

Протокол HTTP / SOAP має перевагу над попереднім протоколом RMI / EJB у тому, що є багатоплатформовим. Таким чином, веб-сервіс може бути написаний на Java та розгорнутий на сервері Glassfish, тоді як клієнт може бути клієнтом .NET або PHP.

Ми розробимо цю архітектуру за трьома різними режимами:

  1. веб-сервіс буде забезпечуватися EJB [Metier]
  2. веб-сервіс буде забезпечуватися веб-додатком, що використовує EJB та [Metier]
  3. веб-сервіс буде забезпечуватися веб-додатком, що використовує Spring

Веб-сервіс можна реалізувати різними способами на сервері Java EE:

  • за допомогою класу з анотацією @WebService, який виконується у веб-контейнері
  • за допомогою EJB з анотацією @WebService, що виконується в контейнері EJB

Почнемо з останньої архітектури.

8.1. Веб-сервіс, реалізований за допомогою EJB

8.1.1. Серверна частина

8.1.1.1. Проєкт NetBeans

Почнемо зі створення нового проекту Maven — копії проекту EJB [mv-pam-ejb-metier-dao-jpa-eclipselink]:

  

З такою архітектурою:

шар [metier] буде веб-сервісом, до якого звертається шар [ui]. Цьому класу не потрібно реалізовувати інтерфейс. Саме анотації перетворюють POJO (звичайний об’єкт Java) на веб-сервіс. Клас [Metier], який реалізує вищезазначений рівень [metier], перетворюється наступним чином:


package metier;

...
@WebService
@Stateless()
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class Metier implements IMetierLocal,IMetierRemote {
  
  // посилання на шари [DAO]
  @EJB
  private ICotisationDaoLocal cotisationDao = null;
  @EJB
  private IEmployeDaoLocal employeDao=null;
  @EJB
  private IIndemniteDaoLocal indemniteDao=null;
  
  
  // отримання відомості про заробітну плату
@WebMethod
  public FeuilleSalaire calculerFeuilleSalaire(String SS,
...
  }
  
  // список співробітників
@WebMethod
   public List<Employe> findAllEmployes() {
...
  }
// важливо — немає методів getter та setter для EJB
 }
  • у рядку 4 анотація @WebService перетворює клас [Metier] на веб-сервіс. Веб-сервіс надає методи своїм клієнтам. Ці методи повинні бути анотовані атрибутом @WebMethod.
  • рядки 19 та 25: обидва методи класу [Metier] стають методами веб-сервісу.
  • рядок 29: важливо видалити методи getter та setter, інакше вони будуть доступні у веб-сервісі, що спричинить помилки безпеки.

Додавання цих анотацій виявляється NetBeans, який після цього змінює характер проєкту:

У [1] у проєкті з’явилася деревоподібна структура [Web Services]. У ній міститься веб-сервіс Metier та його два методи. Серверний додаток можна розгорнути в [2]. Сервер MySQL має бути запущений, а його база даних [dbpam_eclipselink] — існувати та бути заповненою. Можливо, попередньо доведеться видалити [3] та EJB з раніше розглянутого клієнтсько-серверного проєкту EJB, щоб уникнути конфліктів імен. Адже наш новий проект містить ті самі EJB, що й попередній проект.

У [1] ми бачимо, що наш додаток serveur розгорнуто на сервері Glassfish. Після розгортання веб-сервісу його можна протестувати:

  • у [1], у поточному проєкті, ми тестуємо веб-сервіс [Metier]
  • до веб-сервісу можна отримати доступ через різні URL. URL [2] дозволяє протестувати веб-сервіс
  • у [3] — посилання на файл XML, що визначає веб-сервіс. Клієнтам веб-сервісу необхідно знати URL цього файлу. Саме на його основі генерується клієнтський рівень (стаби) веб-сервісу.
  • у файлі [4,5] — форма, що дозволяє протестувати методи, які надає веб-сервіс. Вони представлені разом із параметрами, які може задати користувач.

Наприклад, протестуємо метод [findAllEmployes], який не потребує жодних параметрів:

 

Вище ми тестуємо цей метод. У відповідь отримуємо наведений нижче результат (частковий вигляд). У ньому дійсно вказано двох співробітників із їхніми виплатами. Пропонуємо читачеві аналогічним чином протестувати метод [4], передавши йому три необхідні параметри.

Image

8.1.2. Сторона клієнта

8.1.2.1. Проєкт NetBeans клієнтської частини console

Тепер ми створюємо Java-проект типу [Java Application] для частини client додатка. На червень 2012 року створити проект Maven для цього клієнта не вдалося. Виникає помилка, яка, судячи з усього, відома в мережі, але досі не вирішена.

 

Після створення проєкту ми вказуємо, що він буде клієнтом веб-сервісу, який ми щойно розгорнули на сервері Glassfish:

  • у [2] ми вибираємо новий проєкт і натискаємо кнопку [New File]
  • у [3] вказуємо, що хочемо створити клієнт веб-сервісу
  • за допомогою [4] ми вказуємо проект NetBeans для веб-сервісу
  • у вікні [5] перелічені всі проекти, що мають гілку [Web Services], тут — лише проект [mv-pam-ws-metier-dao-eclipselink].
  • Один проект може розгортати кілька веб-сервісів. У [6] ми вказуємо веб-сервіс, до якого хочемо підключитися.
  • У [7] відображається URL з визначенням веб-сервісу. Цей URL використовується програмними інструментами, які генерують клієнтський рівень, що взаємодіє з веб-сервісом.
  • Клієнтський шар [C] [1], який буде згенеровано, складається з набору класів Java, що будуть розміщені в одному пакеті. Його ім’я встановлено як [8].
  • Після завершення роботи майстра створення клієнта веб-сервісу натисканням кнопки [Finish] створюється вищезазначений рівень [C].

Це відображається у низці змін у проєкті:

  • У наведеному вище [10] відображається дерево [Generated Sources], яке містить класи рівня [C], що дозволяють клієнту [3] взаємодіяти з веб-сервісом. Цей рівень дозволяє клієнту [3] взаємодіяти з рівнями [metier] та [4] так, ніби вони є локальними, а не віддаленими.
  • У [11] з’являється дерево [Web Service References], яке містить перелік веб-сервісів, для яких було згенеровано клієнтський рівень.

Слід зазначити, що у згенерованому шарі [C] [10] ми бачимо класи, які були розгорнуті на стороні сервера: Indemnite, Cotisation, Employe, FeuilleSalaire, ElementsSalaire, Metier. Metier — це веб-сервіс, а інші класи є необхідними для цього сервісу. Може виникнути бажання ознайомитися з їхнім кодом. Ми побачимо, що визначення класів, які після створення екземплярів представляють об’єкти, з якими працює сервіс, складається з визначення полів класу та їхніх методів доступу, а також додавання анотацій, що дозволяють серіалізувати клас у потік XML. Клас Metier перетворився на інтерфейс, що містить два методи, які були анотовані @WebMethod. Кожен із них породжує два класи, наприклад [CalculerFeuilleSalaire.java] та [CalculerFeuilleSalaireResponse.java], де один інкапсулює виклик методу, а інший — його результат. Нарешті, клас MetierService — це клас, який дозволяє клієнту отримати посилання на віддалений бізнес-веб-сервіс:

1
2
3
4
    @WebEndpoint(name = "MetierPort")
    public Metier getMetierPort() {
        return super.getPort(new QName("http://metier/", "MetierPort"), Metier.class);
}

Метод getMetierPort у рядку 2 дозволяє отримати посилання на віддалений веб-сервіс Metier.

8.1.2.2. Консольний клієнт веб-сервісу Metier

Залишилося лише написати клієнт веб-сервісу Metier. Скопіюємо клас [MainRemote] із проєкту [mv-pam-client-metier-dao-jpa-eclipselink], який був клієнтом сервера EJB, у новий проєкт.

  • у [1] — клас клієнта веб-сервісу. У класі [MainRemote] є помилки. Щоб їх виправити, спочатку видалимо всі існуючі інструкції [import] у класі та згенеруємо їх заново за допомогою опції [Fix Imports]. Справа в тому, що деякі класи, які використовує клас [MainRemote], тепер входять до складу згенерованого пакета [client].
  • У [3] фрагмент коду, де інстанціюється шар [metier], — це [3]. Це відбувається за допомогою коду JNDI для отримання посилання на віддалений EJB.

Ми модифікуємо код наступним чином:

  • код JNDI видаляється
  • оскільки клас [PamException] не існує на стороні клієнта, ми видаляємо пов’язаний з ним catch, щоб залишити лише catch у батьківському класі [Exception].
  • у [4] нам залишається отримати посилання на віддалений веб-сервіс [Metier], щоб мати змогу викликати його метод [calculerFeuilleSalaire].
  • У [5] ми за допомогою миші перетягуємо (drag) метод [calculerFeuilleSalaire] із веб-сервісу [Metier], щоб розмістити його (drop) у [4]. Генерується код [6]. Цей загальний код розробник може згодом адаптувати під свої потреби.
  • у рядку 112 видно, що [calculerFeuilleSalaire] є методом класу [client.Metier] (рядок 111). Тепер, коли ми знаємо, як отримати шар [metier], попередній код можна переписати таким чином:
...    
// все гаразд — можна запитати аркуш зарплати
    FeuilleSalaire feuilleSalaire = null;
    Metier metier = null;
    try {
       // інстанціювання шару [metier]
      metier = new MetierService().getMetierPort();
       // розрахунок відомості про заробітну плату
      feuilleSalaire = metier.calculerFeuilleSalaire(args[0], nbHeuresTravaillées, nbJoursTravaillés);
    } catch (Throwable th) {
       // ланцюжок винятків
      System.out.println("Chaîne des exceptions --------------------------------------");
      System.out.println(th.getClass().getName() + ":" + th.getMessage());
      while (th.getCause() != null) {
        th = th.getCause();
        System.out.println(th.getClass().getName() + ":" + th.getMessage());
      }
      System.exit(1);
    }
     // швидке відображення
...

У рядку 7 отримується посилання на веб-сервіс Metier. Після цього код класу не змінюється, за винятком того, що в рядку 10 обробляється не виняток типу [Exception], а більш загальний тип Throwable, базовий клас класу Exception. У разі виникнення винятку ми відображаємо всі вкладені причини цього винятку аж до першопричини.

Ми готові до тестування:

  • перевірити, чи запущено SGBD та MySQL5, чи створено та ініціалізовано базу даних dbpam_eclipselink
  • переконатися, що веб-сервіс розгорнуто на сервері Glassfish
  • зкомпілювати клієнт (Clean and Build)
  • налаштувати виконання клієнта
  
  • запустити клієнт

У консолі відображаються такі результати:

...
Valeurs saisies :
N° de sécurité sociale de l'employé : 254104940426058
Nombre d'heures travaillées : 150
Nombre de jours travaillés : 20

Informations Employé : 
Nom : Jouveinal
Prénom : Marie
Adresse : 5 rue des oiseaux
...

З таким налаштуванням:

Image

отримуємо такі результати:

1
2
3
4
Chaîne des exceptions --------------------------------------
javax.xml.ws.soap.SOAPFaultException:L'employé de n°[xx] est introuvable
com.sun.xml.internal.ws.developer.ServerSideException:L'employé de n°[xx] est introuvable
Java Result: 1

Слід зауважити, що, хоча веб-сервіс [Metier] надсилає виняток типу [PamException], виняток, отриманий клієнтом, має тип [SOAPFaultException]. Навіть у ланцюжку винятків тип [PamException] не з’являється.

8.1.3. Swing-клієнт веб-сервісу Metier


Завдання: перенести клієнт Swing з проєкту [mv-pam-client-ejb-metier-dao-jpa-eclipselink] у новий проєкт, щоб він також став клієнтом веб-сервісу, розгорнутого на сервері Glassfish.


8.2. Веб-сервіс, реалізований веб-додатком

Тепер розглянемо наступну архітектуру:

Веб-сервіс забезпечується веб-додатком, що виконується у веб-контейнері сервера Glassfish. Цей веб-сервіс буде спиратися на EJB [Metier], розгорнутий у контейнері EJB3.

8.2.1. Серверна частина

Ми створюємо веб-додаток:

  • у [1], створюємо новий проєкт
  • у [2], цей проєкт має тип [Web Application]
  • у [3] ми надаємо йому ім’я [mv-pam-ws-ejb-metier-dao-eclipselink]
  • у [4] ми обираємо версію Java EE 6
  • у [6] — створений проєкт

На схемі нижче створений веб-додаток буде виконуватися у веб-контейнері. Він використовуватиме EJB [Metier], який, у свою чергу, буде розгорнуто в контейнері EJB сервера.

Щоб створений веб-додаток мав доступ до класів, пов’язаних із EJB та [Metier], ми додаємо до бібліотек веб-додатка [mv-pam-ws-ejb-metier-dao-eclipselink], залежність від сервера EJB [mv-pam-ejb-metier-dao-eclipselink], який ми вже розглядали.

  • у [1] додаємо проект до залежностей веб-проекту,
  • у [2] вибираємо проект [mv-pam-ejb-metier-dao-eclipselink],
  • у [3] тип залежності — ejb,
  • у [4] область дії залежності — provided, тобто вона буде надана середовищем виконання,
  • у [5] залежність було додано.

Щоб створити той самий веб-сервіс, що й раніше, нам потрібно:

  • створити клас із тегом @Webservice
  • з двома методами calculerFeuilleSalaire та findAllEmployes, позначеними тегом @WebMethod

Створюємо клас [PamWsEjbMetier] у пакеті [pam.ws]:

  

Клас [PamWsEjbMetier] має такий вигляд:

package pam.ws;

import java.util.List;
import javax.ejb.EJB;
import javax.jws.WebMethod;
import javax.jws.WebService;
import jpa.Employe;
import metier.FeuilleSalaire;
import metier.IMetier;
import metier.IMetierLocal;

@WebService
public class PamWsEjbMetier implements IMetier{

  @EJB
  private IMetierLocal metier;

  @WebMethod
  public FeuilleSalaire calculerFeuilleSalaire(String SS, double nbHeuresTravaillées, int nbJoursTravaillés) {
    return metier.calculerFeuilleSalaire(SS, nbHeuresTravaillées, nbJoursTravaillés);
  }

  @WebMethod
  public List<Employe> findAllEmployes() {
    return metier.findAllEmployes();
  }

}
  • рядки 7–10: клас імпортує класи з модулів EJB та [pam-serveurws-metier-dao-jpa-eclipselink], проект Maven яких було додано до залежностей проекту.
  • рядок 12: клас є веб-сервісом
  • рядок 13: він реалізує інтерфейс IMetier, визначений у модулі EJB
  • рядки 18–19: метод calculerFeuilleSalaire експонується як метод веб-сервісу
  • рядки 23–24: метод findAllEmployes експонується як метод веб-сервісу
  • рядки 15–16: локальний інтерфейс EJB [Metier] вставляється у поле рядка 16. Ми використовуємо локальний інтерфейс, оскільки веб-додаток і модуль EJB виконуються в одному й тому ж JVM.
  • рядки 20 і 25: методи calculerFeuilleSalaire та findAllEmployes делегують свою обробку однойменним методам класу EJB [Metier]. Отже, клас слугує лише для того, щоб надати віддаленим клієнтам доступ до методів EJB та [Metier] як до методів веб-сервісу.

У NetBeans веб-додаток розпізнається як такий, що надає веб-сервіс:

Щоб розгорнути веб-сервіс на сервері GlassFish, нам потрібно розгорнути одночасно:

  • веб-модуль у веб-контейнер сервера
  • модуль EJB у контейнер EJB сервера

Для цього нам потрібно створити додаток типу [Enterprise Application], який розгорне обидва модулі одночасно. Для цього обидва проекти мають бути завантажені в NetBeans [2].

Після цього ми створюємо новий проєкт [3].

  • у [4] вибираємо тип проекту [Enterprise Application].
  • у [5] ми даємо назву проекту
  • у [6] ми налаштовуємо проект. Версія Java для EE — це Java EE 6. Корпоративний проект можна створити з двома модулями: модулем EJB та веб-модулем. У цьому випадку корпоративний проєкт буде інкапсулювати веб-модуль та модуль EJB, які вже створено та завантажено в NetBeans. Тому ми не вимагаємо створення нових модулів.
  • У [7] — так створено корпоративний проєкт [mv-pam-webapp-ear]. Одночасно було створено ще один проєкт Maven — [mv-pam-webapp]. Ми ним не займатимемося.
  • У [8] ми додаємо залежності до корпоративного проєкту
  • у [9] додаємо веб-проект типу war,
  • у [10] додаємо проект EJB типу ejb,
  • у [11] — корпоративний проєкт із двома залежностями.

Ми компілюємо корпоративний проєкт за допомогою команди «Clean and Build». Ми майже готові розгорнути його на сервері Glassfish. Перед цим може знадобитися вивантажити додатки, які вже завантажені на сервер, щоб уникнути можливих конфліктів імен EJB та [11]:

Сервер MySQL має бути запущений, а база даних [dbpam_eclipselink] — доступна та заповнена. Після цього можна розгорнути корпоративний додаток [12]. У [13] можна побачити, що вона була успішно розгорнута на сервері Glassfish.

Ми можемо протестувати веб-сервіс, який щойно було розгорнуто:

  • в [1], ми просимо протестувати веб-сервіс [PamWsEjbMetier]
  • на [2] — тестову сторінку. Проведення тестів залишаємо на розсуд читача.

8.2.2. Клієнтська частина


Завдання: дотримуючись підходу, описаного в параграфі 8.1.2.1, створити консольний клієнт для вищезазначеного веб-сервісу.


8.3. Веб-сервіс, реалізований за допомогою Spring та Tomcat

Тепер розглянемо таку архітектуру:

Веб-сервіс забезпечується веб-додатком, що виконується у веб-контейнері сервера Tomcat. Архітектура додатка буде такою:

Ми будемо спиратися на проект [mv-pam-spring-hibernate], створений у розділі 5.11:

  

8.3.1. Серверна частина

Ми створюємо веб-додаток Maven під назвою [mv-pam-ws-spring-tomcat] [1]:

Ми змінюємо файл [pom.xml], щоб включити до нього такі залежності [2]:


  <dependencies>
    <dependency>
      <groupId>${project.groupId}</groupId>
      <artifactId>mv-pam-spring-hibernate</artifactId>
      <version>${project.version}</version>
    </dependency>
    <!-- Залежності Apache CXF -->
    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-frontend-jaxws</artifactId>
      <version>2.2.12</version>
    </dependency>
    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-transports-http</artifactId>
      <version>2.2.12</version>
    </dependency>
</dependencies>
  • рядки 3–7: залежність від проєкту [spring-pam-jpa-hibernate],
  • рядки 8–17: залежності від фреймворку Apache CXF та [http://cxf.apache.org/]. Цей фреймворк полегшує створення веб-сервісів.

Цей файл [pom.xml] містить численні залежності [2].

Повернемося до архітектури додатка:

Виклики веб-сервісу, який ми будемо створювати, обробляються сервлетом фреймворку CXF. У файлі [WEB-INF / web.xml] це виглядає наступним чином:


<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <display-name>mv-pam-ws-spring-tomcat</display-name>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
<!--   Налаштування CXF -->
  <servlet>
    <servlet-name>CXFServlet</servlet-name>
    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>CXFServlet</servlet-name>
    <url-pattern>/ws/*</url-pattern>
  </servlet-mapping>
  <session-config>
    <session-timeout>
      30
    </session-timeout>
  </session-config>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>
  • фреймворк CXF залежить від Spring. Рядки 4–6: оголошується слухач. Відповідний клас завантажуватиметься одночасно з веб-додатком. Він використовуватиме файл конфігурації Spring [WEB-INF / applicationContext.xml]:
  • рядки 8–12: сервлет CXF, який буде обробляти виклики до веб-сервісу, який ми створимо,
  • рядки 13–16: запити URL, що обробляються сервлетом CXF, матимуть формат /ws/*. Інші запити не оброблятимуться сервлетом CXF.

Щоб визначити веб-сервіс, ми визначаємо інтерфейс та його реалізацію:

Інтерфейс [IWsMetier] матиме такий вигляд:


package pam.ws;

import javax.jws.WebService;
import metier.IMetier;

@WebService
public interface IWsMetier extends IMetier{
  
}
  • рядок 7: інтерфейс [IWsMetier] походить від інтерфейсу [IMetier] з рівня [métier] проекту [mv-pam-spring-hibernate],
  • рядок 6: інтерфейс [IWsMetier] є інтерфейсом веб-сервісу.

Клас реалізації цього інтерфейсу такий:


package pam.ws;

import java.util.List;
import javax.jws.WebMethod;
import javax.jws.WebService;
import jpa.Employe;
import metier.FeuilleSalaire;
import metier.IMetier;

@WebService
public class PamWsMetier implements IWsMetier {

  // бізнес-шар
  private IMetier metier;
  
  // конструктор
  public PamWsMetier(){
    
  }
  
  @WebMethod
  public FeuilleSalaire calculerFeuilleSalaire(String SS, double nbHeuresTravaillees, int nbJoursTravailles) {
    return metier.calculerFeuilleSalaire(SS, nbHeuresTravaillees, nbJoursTravailles);
  }

  @WebMethod
  public List<Employe> findAllEmployes() {
    return metier.findAllEmployes();
  }
  
  // методи getter та setter

  public void setMetier(IMetier metier) {
    this.metier = metier;
  }
  
}
  • рядок 11: клас [PamWsMetier] реалізує визначений вище інтерфейс,
  • рядок 10: визначає клас як веб-сервіс,
  • рядок 14: шар [métier] буде ін'єктований Spring,
  • рядки 21, 26: анотація @WebMethod перетворює метод на метод, доступний через веб-сервіс,
  • рядки 23, 28: методи реалізовано за допомогою шару [métier].

Залишається визначити вміст конфігураційного файлу Spring [applicationContext.xml]:

Його вміст такий:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-2.0.xsd 
       http://www.springframework.org/schema/tx 
       http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
       http://cxf.apache.org/jaxws
       http://cxf.apache.org/schemas/jaxws.xsd">
  
  <!-- Apache CXF -->
  <import resource="classpath:META-INF/cxf/cxf.xml" />
  <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
  <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />  

  <!-- нижні шари -->
  <import resource="classpath:spring-config-metier-dao.xml" />  
  
  <!-- веб-сервіс -->
  <bean id="wsMetier" class="pam.ws.PamWsMetier">
    <property name="metier" ref="metier"/>
  </bean>
  <jaxws:endpoint id="wsmetier"
                  implementor="#wsMetier"
                  address="/metier">
  </jaxws:endpoint>  

</beans>
  • рядки 13–15: імпортуються конфігураційні файли Apache CXF. Їх шукають у Classpath проекту (атрибут classpath:),
  • рядки 4, 9, 10: оголошуються простори імен, специфічні для Apache CXF,
  • рядок 18: імпортується файл конфігурації Spring з проєкту [mv-pam-spring-hibernate],
  • рядки 21–23: визначають bean веб-сервісу з його залежністю від шару [métier] (рядок 22),
  • рядки 24–27: визначають сам веб-сервіс,
    • рядок 25: bean Spring, що реалізує веб-сервіс, — це той, що визначений у рядку 21;
    • рядок 26: визначає URL, на якому буде доступний веб-сервіс, у даному випадку /metier. У поєднанні з форматом, який повинні мати URL, що обробляються Apache CXF (див. файл web.xml), ця URL стає /ws/metier.

Наш проєкт готовий до запуску. Запускаємо його (Run) і запитуємо URL [http://localhost:8080/mv-pam-ws-spring-tomcat/ws] у браузері:

Image

На сторінці перелічено всі розгорнуті веб-сервіси. У даному випадку їх лише один. Переходимо за посиланням WSDL:

Текст, що відображається [1], — це вміст файлу XML, який визначає функціонал веб-сервісу, спосіб його виклику та типи відповідей, які він надсилає. Зверніть увагу на URL, [2] та WSDL у цьому файлі. Усі клієнти веб-сервісу повинні знати ці значення.

8.3.2. Клієнтська частина


Завдання: дотримуючись підходу, описаного в розділі 8.1.2.1, створити консольний клієнт для вищезгаданого веб-сервісу.


Примітка: щоб вказати URL для файлу WSDL веб-сервісу, слід виконати такі дії:

У поле [3] вкажіть значення URL, яке раніше було вказано у полі [2].