еда полезней и вкусней.
410013796724260
• Webmoney
R335386147728
Z369087728698
Клиент web-сервиса SOAPДанная статья является продолжением описания WEB-сервиса SOAP. С общим описанием веб-сервисов (что это такое и какие типы веб-сервисов используются) можно познакомиться здесь. Создание и тестирование WEB-сервиса SOAP рассмотрено отдельно на практическом примере в среде разработки Eclipse. Для описания WEB-сервиса SOAP используется язык WSDL В этой статье на рабочем примере будем рассматривать вопрос создания клиента веб-сервисов SOAP. В качестве «подопытных» используем действующие на момент написания статьи два веб-сервиса. Первый веб-сервис http://www.webservicex.net/uszip.asmx используем для получения почтовых значений ZIP районов города New York. На следующем скриншоте представлены методы WEB-сервиса, которые Вы можете увидеть при нажатии на ссылку. Используем второй по списку метод GetInfoByCity.
Второй веб-сервис BELAVIA включает метод получения списка аэропортов GetAirportsList и метод получения списка рейсов с информацией о вылете/прилёте и состоянии рейса GetTimeTable. По ссылке можно перейти на страницу описания веб-сервиса и посмотреть параметры методов web-сервиса BELAVIA, а также примеры запросов и ответов. В примере будем получать список аэропортов, используя метод GetAirportsList. Примечание : если по указанным выше ссылкам можно открыть описания WEB-сервисов, то рассматриваемый на странице пример сможет выполнить запрос и получить ответ. Структура сообщений SOAPС WEB-сервисом SOAP «разговаривают на языке сообщений» определенного формата. Структура SOAP-сообщения состоит из оболочки, разделенной на две главные части: секция с описанием заголовка <soap:Header> и секция с телом сообщения <soap:Body>. Следующий код демонстрирует сообщение запроса списка аэропортов веб-сервиса BELAVIA.
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns="http://webservices.belavia.by">
<soap:Header/>
<soap:Body>
<ns:GetAirportsList/>
</soap:Body>
</soap:Envelope>
Оболочка сообщения (<soap:Envelope>) содержит элементы Header и Body, которые также, как и Envelope принадлежат пространству имен http://schemas.xmlsoap.org/soap/envelope/. SOAPConnectionFactory - класс создания подключения и SOAP сообщенияДля работы с WEB-сервисом SOAP удобнее всего использовать SAAJ (SOAP with Attachments API for Java), который представляет программный интерфейс Java для сообщений SOAP. В пакет SAAJ включен класс SOAPConnection, который позволяет отправлять запросы веб-сервису. Объект подключения SOAPConnection создается с помощью SOAPConnectionFactory, который также используется и для создания SOAP сообщения (SOAPMessage). Следующий код демонстрирует создание SOAPConnection и SOAPMessage.
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPPart;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPConnectionFactory;
...
SOAPConnectionFactory soapConnFactory;
SOAPConnection soapConnection ;
MessageFactory messageFactory ;
try {
// Создание соединения
soapConnFactory = SOAPConnectionFactory.newInstance();
soapConnection = soapConnFactory.createConnection();
// Создание сообщения
messageFactory = MessageFactory.newInstance();
SOAPMessage message = messageFactory.createMessage();
// Компоненты сообщения
SOAPPart soapPart = message.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
SOAPBody body = envelope.getBody();
// Закрываем соединение
soapConnection.close();
} catch(Exception e) {
System.out.println(e.getMessage());
}
С помощью объекта MessageFactory создается объект сообщения SOAPMessage, у которого первоначально разделы envelope и header пусты. Объект SOAPPart содержит envelope, в который включается тело сообщения. Для формирования тела сообщения определяется ссылка SOAPBody. SAAJ также позволяет напрямую создать объект SOAPPart-сообщения из внешнего файла. Так часто отправляемый запрос можно поместить в файл weather.msg, чтобы при необходимости его содержимое загружать в тело SOAP вместо ручного создания. Следующий код демонстрирует формирование тела SOAP сообщения с использованием потока ввода.
// Создание сообщения
messageFactory = MessageFactory.newInstance();
SOAPMessage message = messageFactory.createMessage();
// Компоненты сообщения
SOAPPart soapPart = message.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
SOAPBody body = envelope.getBody();
// Формирование сообщения
StreamSource msgSrc;
FileInputStream fis = FileInputStream("weather.msg");
msgSrc = new StreamSource(fis);
soapPart.setContent(msgSrc);
//Сохранение сообщения
message.saveChanges();
Класс StreamSource открывает файловый поток ввода FileInputStream и читает готовое к отправке сообщение. Пример клиента WEB-сервиса SOAPСоздадим простенький проект в Eclipse, структура которого представлена на следующем скриншоте. В проект включим библиотеку saaj.jar и класс SoapClientExample, который будет отправлять WEB-сервисам запросы и получать от них ответы. Проще проект и не представить, но какие возможности ... .
Библиотека saaj.jar позволяет использовать в клиенте web-сервиса SOAP программный интерфейс Java для сообщений SAAJ (SOAP with Attachments API for Java). Структура класса SoapClientExampleSoapClientExample включает методы формирования SOAP сообщения (createSoapEnvelope, createSOAPRequest) и метод вызова веб-сервиса (callSoapWebService). Код методов представлен ниже. Переменные, определяющие параметры Web-сервиса и запроса, вынесены из методов и объявлены глобальными. Метод setSoapParams в зависимости от установленного флага belavia инициализирует параметры запроса одного из используемых web-сервисов.
package com.example;
import javax.xml.soap.*;
public class SoapClientExample
{
private boolean belavia = true;
private String namespaceURI = null;
private String soapUrl = null;
private String serviceName = null;
private String namespace = null;
private String soapAction = null;
public SoapClientExample()
{
setSoapParams();
callSoapWebService(soapUrl, soapAction);
}
private void setSoapParams()
{
if (belavia) {
namespaceURI = "http://webservices.belavia.by";
soapUrl = "http://86.57.245.235/TimeTable/Service.asmx";
serviceName = "GetAirportsList";
} else {
namespaceURI = "http://www.webserviceX.NET";
soapUrl = "http://www.webservicex.net/uszip.asmx";
serviceName = "GetInfoByCity";
}
namespace = "ns"; // namespace
soapAction = namespaceURI + "/" + serviceName;
}
private void createSoapEnvelope(SOAPMessage soapMessage) throws SOAPException
{
// код
}
private SOAPMessage createSOAPRequest(String soapAction) throws Exception
{
// код
}
private void callSoapWebService(String destination,
String soapService)
{
// код
}
public static void main(String[] args)
{
new SoapClientExample();
System.exit(0);
}
}
Метод создания оболочки сообщенияМетод createSoapEnvelope формирует тело сообщения в зависимости от установленного флага belavia.
private void createSoapEnvelope(SOAPMessage soapMessage)
throws SOAPException
{
SOAPPart soapPart = soapMessage.getSOAPPart();
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration(namespace, namespaceURI);
// SOAP Body
SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem;
SOAPElement soapBodyElem1;
if (belavia) {
soapBody.addChildElement(serviceName, namespace);
} else {
soapBodyElem =soapBody.addChildElement(serviceName, namespace);
soapBodyElem1=soapBodyElem.addChildElement("USCity",namespace);
soapBodyElem1.addTextNode("New York");
}
}
Метод создания запроса к веб-сервисуМетод createSOAPRequest подготавливает SOAP сообщение и вызывает метод формирования тела сообщения createSoapEnvelope.
private SOAPMessage createSOAPRequest(String soapAction)
throws Exception
{
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
createSoapEnvelope(soapMessage);
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", soapAction);
soapMessage.saveChanges();
// Печать XML текста запроса
System.out.println("Request SOAP Message:");
soapMessage.writeTo(System.out);
System.out.println("\n");
return soapMessage;
}
Метод вызова WEB-сервисаМетод callSoapWebService используется для отправки запроса и получения ответа. Отправка сообщений SOAP и получение ответов выполняются за один шаг, т.е. синхронно. Сообщение отправляется в момент вызова метода call объекта SOAPConnection, который принимает в качестве аргументов адрес назначения и само сообщение. После этого соединение не закрывается и находится в ожидании ответа. В качестве ответа метод возвращает другой объект также типа SOAPMessage. Вывод результата запроса выводится в консоль. Но поскольку полученный объект типа SOAPMessage, также является сообщением SOAP, то как и любое XML-сообщение, его можно трансформировать с помощью XSLT. SOAP позволяет выполнить XSLT-преобразование напрямую. В следующем листинге приводится метод printSOAPMessage, в котором выполняется данное преобразование.
Примечание :
boolean useXSLT = true;
...
private void callSoapWebService(String destination,
String soapAction)
{
SOAPConnectionFactory soapFactory = null;
SOAPConnection soapConnect = null;
SOAPMessage soapRequest = null;
SOAPMessage soapResponse = null;
try {
// Создание SOAP Connection
soapFactory = SOAPConnectionFactory.newInstance();
soapConnect = soapFactory.createConnection();
// Создание SOAP Message для отправки
soapRequest = createSOAPRequest(soapAction);
// Получение SOAP Message
soapResponse = soapConnect.call(soapRequest, destination);
// Печать SOAP Response
if (!useXSLT) {
System.out.println("Response SOAP Message:");
soapResponse.writeTo(System.out);
System.out.println();
} else
printSOAPMessage (soapResponse);
soapConnect.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private void printSOAPMessage (SOAPMessage soapResponse)
{
TransformerFactory transformerFactory;
Transformer transformer;
try {
// Создание XSLT-процессора
transformerFactory = TransformerFactory.newInstance();
transformer = transformerFactory.newTransformer();
// Получение содержимого ответа
Source content;
content = soapResponse.getSOAPPart().getContent();
// Определение выходного потока
StreamResult result = new StreamResult(System.out);
transformer.transform(content, result);
System.out.println();
} catch (Exception e) {
e.printStackTrace();
}
}
При использовании XSLT в методе printSOAPMessage сначала создается объект Transformer. После этого определяется содержимое content типа javax.xml.transform.Source. Поскольку content выводится только в консоль (System.out), то таблица стилей не используется. При обработке можно выделить как оболочку, так и тело сообщения. Тестирование примераПрограмма выводит в консоль тексты SOAP сообщений как запроса, так и ответа. Ниже представлен результат выполнения запроса к сервису получения ZIP значений города Нью-Йорка. Ответ представлен в виде массива данных (отображены только первые два и последний элементы массива).
Request SOAP Message:
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns="http://www.webserviceX.NET">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<ns:GetInfoByCity>
<ns:USCity>New York</ns:USCity>
</ns:GetInfoByCity>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
-----------------------------------------------------------
Response SOAP Message:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetInfoByCityResponse xmlns="http://www.webserviceX.NET">
<GetInfoByCityResult>
<NewDataSet xmlns="">
<Table>
<CITY>New York</CITY>
<STATE>NY</STATE>
<ZIP>10001</ZIP>
<AREA_CODE>212</AREA_CODE>
<TIME_ZONE>E</TIME_ZONE>
</Table>
<Table>
<CITY>New York</CITY>
<STATE>NY</STATE>
<ZIP>10002</ZIP>
<AREA_CODE>212</AREA_CODE>
<TIME_ZONE>E</TIME_ZONE>
</Table>
...
<Table>
<CITY>New York</CITY>
<STATE>NY</STATE>
<ZIP>10292</ZIP>
<AREA_CODE>212</AREA_CODE>
<TIME_ZONE>E</TIME_ZONE>
</Table>
</NewDataSet>
</GetInfoByCityResult>
</GetInfoByCityResponse>
</soap:Body>
</soap:Envelope>
Ответ на запрос получения списка аэропортов также представлен в виде массива данных (отображены только четыре первых и последний элементы массива).
Request SOAP Message:
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns="http://webservices.belavia.by">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<ns:GetAirportsList/>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
-----------------------------------------------------------
Response SOAP Message:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetAirportsListResponse
xmlns="http://webservices.belavia.by/">
<GetAirportsListResult>
<Airport IATA="ADB" Name="Izmir" />
<Airport IATA="AER" Name="Sochi(Adler)" />
<Airport IATA="ALA" Name="Almaty" />
<Airport IATA="AMS" Name="Amsterdam" />
. . .
<Airport IATA="ZTH" Name="Zakynthos" />
</GetAirportsListResult>
</GetAirportsListResponse>
</soap:Body>
</soap:Envelope>
Скачать примерИсходный код примера в виде проекта Eclipse soap-client, включающий библиотеку saaj.jar, можно скачать здесь (23 Кб). Пример SOAP клиента с авторизацей представлен здесь. |
