Заголовок топіка – це справді питання, т.к. я сам не знаю, що це і вперше спробую попрацювати з цим у рамках цієї статті. Єдине, що можу гарантувати, що код, поданий нижче, працюватиме, проте мої фрази будуть лише припущеннями та здогадками про те, як я сам усе це розумію. Отже, поїхали.
Вступ
Почати треба з того, навіщо створювалася концепція веб-сервісів. На момент появи цього поняття у світі вже існували технології, що дозволяють програмам взаємодіяти на відстані, де одна програма могла викликати якийсь метод в іншій програмі, яка при цьому могла бути запущена на комп'ютері, розташованому в іншому місті чи навіть країні. Все це скорочено називається RPC (Remote Procedure Calling – віддалений виклик процедур). Як приклади можна навести технології CORBA, а Java – RMI (Remote Method Invoking – віддалений виклик методів). І начебто у них добре, особливо у CORBA, т.к. з нею можна працювати будь-якою мовою програмування, але чогось все ж таки не вистачало. Вважаю, що мінусом CORBA є те, що вона працює через якісь свої мережеві протоколи замість простого HTTP, котрий пролізе через будь-який firewall. Ідея веб-сервісу полягала у створенні такого RPC, який засовуватиметься в HTTP пакети. Так розпочалася розробка стандарту. Які у цього стандарту базові поняття:- SOAP . Перш ніж викликати віддалену процедуру, потрібно описати цей виклик у XML файлі формату SOAP. SOAP – це просто одна з численних розміток XML, яка використовується у веб-сервісах. Все, що ми хочемо кудись відправити через HTTP, спочатку перетворюється на XML опис SOAP, потім засовується в HTTP пакет і посилається на інший комп'ютер у мережі TCP/IP.
- WSDL . Існує веб-сервіс, тобто. програма, методи якої можна віддалено викликати. Але стандарт вимагає, щоб до цієї програми додався опис, в якому сказано, що «так, ви не помаболися – це дійсно веб-сервіс і можна у нього викликати такі-то методи». Такий опис є ще одним файлом XML, який має інший формат, а саме WSDL. Тобто. WSDL – це просто XML-файл опису веб-сервісу і більше нічого.
Загальний підхід
У веб-сервісах завжди є клієнт та сервер. Сервер – це і є наш веб-сервіс і іноді його називають endpoint (типу як кінцева точка, куди доходять SOAP повідомлення від клієнта). Нам потрібно зробити таке:- Описати інтерфейс нашого веб-сервісу
- Реалізувати цей інтерфейс
- Запустити наш веб-сервіс
- Написати клієнта та віддалено викликати потрібний метод веб-сервісу
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!
Якщо не побачабо, то, мабуть, забули запустити веб-сервіс.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ