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 клиента с авторизацей представлен здесь. |