У цій короткій нотатці я хотів би повернутися до коду клієнта веб-сервісу, який ми написали на попередньому кроці . При цьому я припускатиму, що у вас відкрита IDEA, а в ній проект із Кроку 1. У цьому проекті має бути запущений наш веб-сервіс:
package ru.codegym.client;
// нужно, чтобы получить wsdl описание и через него
// дотянуться до самого веб-сервиса
import java.net.URL;
// такой эксепшн возникнет при работе с об'єктом URL
import java.net.MalformedURLException;
// классы, чтобы пропарсить xml-ку c wsdl описанием
// и дотянуться до тега service в нем
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
// интерфейс нашего веб-сервиса (нам больше и нужно)
import ru.codegym.ws.HelloWebService;
public class HelloWebServiceClient {
public static void main(String[] args) throws MalformedURLException {
// создаем ссылку на wsdl описание
URL url = new URL("http://localhost:1986/wss/hello?wsdl");
// Параметры следующего конструктора смотрим в самом первом теге WSDL описания - definitions
// 1-ый аргумент смотрим в атрибуте targetNamespace
// 2-ой аргумент смотрим в атрибуте name
QName qname = new QName("http://ws.codegym.cc/", "HelloWebServiceImplService");
// Теперь мы можем дотянуться до тега service в wsdl описании,
Service service = Service.create(url, qname);
// а далее и до вложенного в него тега port, чтобы
// получить ссылку на удаленный от нас об'єкт веб-сервиса
HelloWebService hello = service.getPort(HelloWebService.class);
// Ура! Теперь можно вызывать удаленный метод
System.out.println(hello.getHelloString("JavaRush"));
}
}
Зверніть увагу, скільки нам потрібно знати заздалегідь. Крім того, що потрібен доступ до wsdl опису (без цього, вибачте, ніяк):
URL url = new URL("http://localhost:1986/wss/hello?wsdl");
потрібно самому відкрити цей xml файл і подивитися тег definitions
, а в ньому атрибути targetNamespace
і name
, щоб викликати конструктор QName
:
QName qname = new QName("http://ws.codegym.cc/", "HelloWebServiceImplService");
потім потрібно вручну підключитися до тегу service
:
Service service = Service.create(url, qname);
а в ньому до тегу port
:
HelloWebService hello = service.getPort(HelloWebService.class);
і лише після цього нам можна викликати віддалений метод:
hello.getHelloString("JavaRush")
Постає питання: для цього наші прадіди гинули на полях битв, щоб ми тепер все це робабо вручну? А якщо це навіть не наш веб-сервіс, а чужий. Тоді цей процес буде ще неприємнішим. XML формат створений для читання машиною, а чи не людиною. Тож давайте змусимо машину виконувати брудну роботу, а самі насолодимося процесом. І тому нам і робити особливо нічого треба, т.к. до складу нашого улюбленого SDK, який Java називається JDK, входить спеціальна утиліта wsimport . Але про все по порядку… Спершу давайте створимо новий проект у IDEA, вибравши в меню пункт File > New Project… і давши проекту ім'я HelloWS . Коли нас запитають, де відкрити новий проект, то потрібно відповісти New Window, тобто. у новому вікні, оскільки ще раз зауважу, що дуже важливо, щоб попередній проект було відкрито, т.к. ми пам'ятаємо ще з Кроку 1, що у нас у тому проекті запущено наш веб-сервіс. Можна, звичайно, запустити його просто через консоль windows, але я цього робити не люблю. З нового проекту відкриємо консоль, вибравши View > Tool Windows > Terminal або просто натиснувши Alt+F12 . Зараз ми знаходимося в корені проекту, а потрібно потрапити до папки src , тому вводимо в консоль наступну команду: cd src
Тепер настав час скористатися утилітою wsimport . Вона працює за таким принципом: ми передаємо їй WSDL опис, а вона у відповідь створює файли заглушки (так звані,Stub
-Класи), які вже містять всю необхідну нам функціональність для доступу до веб-сервісу. Ці класи розмістяться у пакеті com.codegym.ws
. Якщо запитаєте, звідки береться ім'я пакета, відповім: ім'я пакета – це розгорнуте в зворотний бік цільовий простір імен з WSDL опису. Згадуємо атрибут targetNamespace
у тезі definitions
з WSDL . Там у нас було написано таке http:// ws.codegym.cc/
. І це не адресаа сайту, це так прийнято в XML описувати простори імен і якщо відкинути http://
і розгорнути те, що залишиться, у зворотному порядку, то отримаємо наше ім'я пакета. Отже, запустимо утиліту: wsimport -keep http://localhost:1986/wss/hello?wsdl
Щоб вона спрацювала, потрібно, щоб шлях до неї був прописаний у змінній оточенні PATHабо можна просто використовувати повний шлях до неї. У мене вона розташовується в папці C:\Program Files\Java\jdk1.8.0_31\bin . Зверніть увагу, що все, що потрібно зробити – це передати через ключ –keep файл WSDL , який у нас доступний віддалено за посиланням, якщо ми звичайно не відключабо веб-сервіс. Що це за класи заглушки? Їх лише два. Один із них – цеHelloWebService
, який по суті є тим самим інтерфейсом веб-сервісу, який ми створювали вручну на Кроку 1. Різниця мінімальна і вона полягає в тому, що трохи інакше використовуються інструкції, з якими ми вже зустрічалися, а також використовуються додаткові інструкції, про які я нічого не знаю, але якщо у нас і без них раніше все працювало, то вони, очевидно, мають не обов'язковий характер. Другий клас заглушка – це те HelloWebServiceImplService
, що успадковується від класу Service
. З класомService
ми вже стикалися у нашому клієнті. Наводити код цього не буду, т.к. навряд чи готовий пояснити всі його рядки, але суть класу зводиться до того, що все, що ми раніше писали в клієнті вручну, щоб підключитися до веб-сервісу, у цьому класі створено автоматично і нам достатньо викликати один його метод і все в нас буде в ажурі. Тому перепишемо код нашого клієнта в новому проекті з використанням цих класів і переконаємося, що код виходить більш лаконічним. Для початку в папці src нового проекту створимо пакет com.codegym.client
, а в ньому клас HelloWebServiceClient
із методом main
:
package ru.codegym.client;
// подключаем классы-заглушки
import ru.codegym.ws.*;
public class HelloWebServiceClient {
public static void main(String[] args) {
// подключаемся к тегу service в wsdl описании
HelloWebServiceImplService helloService = new HelloWebServiceImplService();
// получив информацию из тега service подключаемся к самому веб-сервису
HelloWebService hello = helloService.getHelloWebServiceImplPort();
// обращаемся к веб-сервису и выводим результат в консоль
System.out.println( hello.getHelloString("JavaRush Community") );
}
}
Розбір коду елементарний і досить того, що я описав у коментарях. Запустивши клієнта, ми повинні побачити рядок: Hello, JavaRush Community!
При цьому клієнт із проекту з Кроку 1 продовжуватиме працювати і виводити свій текст, який ми в ньому прописали, а саме: Hello, JavaRush!
На цьому, мабуть, можна закінчити цей Крок, т.к. мету його досягнуто. Ми зрозуміли, що якщо є WSDL опис веб-сервісу, то jdk готове надати нам автоматичну генерацію stub
класів-заглушок для спрощення написання клієнта до даного веб-сервісу. На мій погляд, це дуже корисна можливість на випадок, коли хочеться потестувати чужий веб-сервіс і не залазити очима в його опис WSDL . Погляд у майбутнє У наступній статейці про веб-сервіси я хотів би викласти ідеї, як задеплоїти веб-сервіс у контейнер сервлетів Tomcat і в різні сервери додатків, щоб не потрібно було запускати веб-сервіс, як окремий додаток, як ми це робабо на перших 2-х Кроках. Але перед цим, вважаю, краще зробити невеликий відступ на тему, що таке сервлети, контейнери сервлетів і чим вони відрізняються від серверів додатків і звичайних веб-с... . Крім того, доведеться зробити короткий огляд серверів додатків , які, на мій погляд, заслуговують на нашу з вами уваги.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ