JavaRush /Java блог /Random UA /Веб-сервіси. Крок 2. Як спростити написання клієнта?
eGarmin
41 рівень

Веб-сервіси. Крок 2. Як спростити написання клієнта?

Стаття з групи Random UA
У цій короткій нотатці я хотів би повернутися до коду клієнта веб-сервісу, який ми написали на попередньому кроці . При цьому я припускатиму, що у вас відкрита 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-х Кроках. Але перед цим, вважаю, краще зробити невеликий відступ на тему, що таке сервлети, контейнери сервлетів і чим вони відрізняються від серверів додатків і звичайних веб-с... . Крім того, доведеться зробити короткий огляд серверів додатків , які, на мій погляд, заслуговують на нашу з вами уваги.
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ