JavaRush /Java блог /Random UA /Веб-сервіси. Крок 1. Що таке веб-сервіс та як з ним працю...
eGarmin
41 рівень

Веб-сервіси. Крок 1. Що таке веб-сервіс та як з ним працювати?

Стаття з групи Random UA
Заголовок топіка – це справді питання, т.к. я сам не знаю, що це і вперше спробую попрацювати з цим у рамках цієї статті. Єдине, що можу гарантувати, що код, поданий нижче, працюватиме, проте мої фрази будуть лише припущеннями та здогадками про те, як я сам усе це розумію. Отже, поїхали. Веб-сервіси.  Крок 1. Що таке веб-сервіс та як з ним працювати?  - 1

Вступ

Почати треба з того, навіщо створювалася концепція веб-сервісів. На момент появи цього поняття у світі вже існували технології, що дозволяють програмам взаємодіяти на відстані, де одна програма могла викликати якийсь метод в іншій програмі, яка при цьому могла бути запущена на комп'ютері, розташованому в іншому місті чи навіть країні. Все це скорочено називається RPC (Remote Procedure Calling – віддалений виклик процедур). Як приклади можна навести технології CORBA, а Java – RMI (Remote Method Invoking – віддалений виклик методів). І начебто у них добре, особливо у CORBA, т.к. з нею можна працювати будь-якою мовою програмування, але чогось все ж таки не вистачало. Вважаю, що мінусом CORBA є те, що вона працює через якісь свої мережеві протоколи замість простого HTTP, котрий пролізе через будь-який firewall. Ідея веб-сервісу полягала у створенні такого RPC, який засовуватиметься в HTTP пакети. Так розпочалася розробка стандарту. Які у цього стандарту базові поняття:
  1. SOAP . Перш ніж викликати віддалену процедуру, потрібно описати цей виклик у XML файлі формату SOAP. SOAP – це просто одна з численних розміток XML, яка використовується у веб-сервісах. Все, що ми хочемо кудись відправити через HTTP, спочатку перетворюється на XML опис SOAP, потім засовується в HTTP пакет і посилається на інший комп'ютер у мережі TCP/IP.
  2. WSDL . Існує веб-сервіс, тобто. програма, методи якої можна віддалено викликати. Але стандарт вимагає, щоб до цієї програми додався опис, в якому сказано, що «так, ви не помаболися – це дійсно веб-сервіс і можна у нього викликати такі-то методи». Такий опис є ще одним файлом XML, який має інший формат, а саме WSDL. Тобто. WSDL – це просто XML-файл опису веб-сервісу і більше нічого.
Чому так стисло запитаєте ви? А детальніше не можна? Напевно, можна, але для цього доведеться звернутися до таких книг як Машнін Т. «Web-сервіси Java». Там протягом перших 200 сторінок йде докладний опис кожного стандартного тега SOAP і WSDL. Чи варто це робити? На погляд немає, т.к. все це на Java створюється автоматично, а вам потрібно лише написати вміст методів, які передбачається видалено викликати. Так ось у Java з'явився такий API, як JAX-RPC. Якщо хтось не знає, коли кажуть, що в Java є такий-то API, це означає, що є пакет з набором класів, які інкапсулюють технологію, що розглядається. JAX-RPC довго розвивався від версії до версії і зрештою перетворився на JAX-WS. WS, очевидно, означає WebService і можна подумати, що це просте перейменування RPC на популярне нині слівце. Це негаразд, т.к. Тепер веб-сервіси відійшли від початкового задуму і дозволяють не просто викликати віддалені методи, а й просто надсилати повідомлення-документи у форматі SOAP. Навіщо це потрібно я поки не знаю, навряд чи відповідь тут буде «про всяк випадок, раптом знадобиться». Сам би хотів дізнатися від досвідченіших товаришів. Та й останнє, далі з'явився ще JAX-RS для так званих RESTful веб-сервісів, але це тема окремої статті. У цьому вступ можна закінчувати, т.к. далі ми будемо вчитися працювати з JAX-WS. далі з'явився ще JAX-RS для про RESTful веб-сервісів, але це тема окремої статті. У цьому вступ можна закінчувати, т.к. далі ми будемо вчитися працювати з JAX-WS. далі з'явився ще JAX-RS для про RESTful веб-сервісів, але це тема окремої статті. У цьому вступ можна закінчувати, т.к. далі ми будемо вчитися працювати з JAX-WS.

Загальний підхід

У веб-сервісах завжди є клієнт та сервер. Сервер – це і є наш веб-сервіс і іноді його називають endpoint (типу як кінцева точка, куди доходять SOAP повідомлення від клієнта). Нам потрібно зробити таке:
  1. Описати інтерфейс нашого веб-сервісу
  2. Реалізувати цей інтерфейс
  3. Запустити наш веб-сервіс
  4. Написати клієнта та віддалено викликати потрібний метод веб-сервісу
Запуск веб-сервісу можна проводити різними способами: або описати клас з методом mainі запустити веб-сервіс безпосередньо, як сервер, або задеплоїти його на сервер типу Tomcat або будь-який інший. У другому випадку ми самі не запускаємо новий сервер і не відкриваємо ще один порт на комп'ютері, а просто говоримо контейнеру сервлетів Tomcat, що «ми написали тут класи веб-сервісу, опублікуй їх, будь ласка, щоб усі, хто до тебе звернутися могли нашим веб-сервіс скористатися». Незалежно від способу запуску веб-сервісу, клієнт у нас буде той самий.

Сервер

Запустимо IDEA і створимо новий проект Create New Project . Вкажемо ім'я HelloWebService і натиснемо кнопку Next , далі кнопку Finish . У папці src створимо пакет com.codegym.ws . У цьому пакеті створимо інтерфейс HelloWebService:
package ru.codegym.ws;

// это аннотации, т.е. способ отметить наши классы и методы,
// як связанные с веб-сервисной технологией
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

// говорим, что наш интерфейс будет работать як веб-сервис
@WebService
// говорим, что веб-сервис будет использоваться для вызова методов
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface HelloWebService {
    // говорим, что этот метод можно вызывать удаленно
    @WebMethod
    public String getHelloString(String name);
}
У цьому коді класи WebServiceі WebMethodє так званими інструкціями і нічого не роблять, окрім як позначають наш інтерфейс та його метод, як веб-сервіс. Це саме стосується і класу SOAPBinding. Різниця лише в тому, що SOAPBindingце анотація з параметрами. У разі використовується параметр styleзі значенням, що говорить, що веб-сервіс працюватиме через повідомлення-документи, бо як класичний RPC, тобто. для виклику методу. Давайте реалізуємо логіку нашого інтерфейсу та створимо у нашому пакеті клас HelloWebServiceImpl. До речі, зауважу, що закінчення класу на Impl – це угода Java, за якою так позначають реалізацію інтерфейсів (Impl – від слова implementation, тобто реалізація). Це не вимога і ви вільні назвати клас як хочете, але правила хорошого тону того вимагають:
package ru.codegym.ws;

// таже анотація, что и при описании интерфейса,
import javax.jws.WebService;

// но здесь используется с параметром endpointInterface,
// указывающим полное ім'я класса интерфейса нашего веб-сервиса
@WebService(endpointInterface = "com.codegym.ws.HelloWebService")
public class HelloWebServiceImpl implements HelloWebService {
    @Override
    public String getHelloString(String name) {
        // просто возвращаем приветствие
        return "Hello, " + name + "!";
    }
}
Запустимо наш веб-сервіс як самостійний сервер, тобто. без участі будь-яких Tomcat та серверів додатків (це тема окремої розмови). Для цього в структурі проекту в папці src створимо пакет com.codegym.endpoint, а в ньому створимо клас HelloWebServicePublisherіз методом main:
package ru.codegym.endpoint;

// класс, для запуска веб-сервера с веб-сервисами
import javax.xml.ws.Endpoint;
// класс нашего веб-сервиса
import ru.codegym.ws.HelloWebServiceImpl;

public class HelloWebServicePublisher {
    public static void main(String... args) {
        // запускаем веб-сервер на порту 1986
        // и по адресау, указанному в первом аргументе,
        // запускаем веб-сервис, передаваемый во втором аргументе
        Endpoint.publish("http://localhost:1986/wss/hello", new HelloWebServiceImpl());
    }
}
Тепер запустимо цей клас, натиснувши Shift+F10 . У консолі нічого не з'явиться, але сервер запущено. У цьому можна переконатися, набравши в браузері рядок http://localhost:1986/wss/hello?wsdl . Сторінка, що відкрилася, з одного боку, доводить, що у нас на комп'ютері (localhost) запустився веб-сервер (http://) на порту 1986, а, з іншого боку, показує WSDL опис нашого веб-сервісу. Якщо ви зупините програму, то опис стане недоступним, як і сам веб-сервіс, тому робити цього не будемо, а перейдемо до написання клієнта.

Клієнт

У папці проекту src створимо пакет com.codegym.client, а в ньому клас HelloWebServiceClientіз методом main:
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"));
    }
}
Максимум коментарів за кодом я дав у лістингу. Додати мені нічого, тому запускаємо (Shift+F10). Ми повинні в консолі побачити текст: Hello, JavaRush!Якщо не побачабо, то, мабуть, забули запустити веб-сервіс.

Висновок

У цьому топіці був представлений короткий екскурс до веб-сервісів. Ще раз скажу, що багато з того, що я написав – це мої здогади щодо того, як це працює, і тому мені не варто довіряти. Буду вдячний, якщо знаючі люди мене виправлять, адже тоді я чогось навчуся. UPD. Продовжуємо розмову
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ