410013796724260
• Webmoney
R335386147728
Z369087728698
SOAP клиент с авторизациейОписание и примеры использования SOAP клиентов открытых web-сервисов широко представлены как в интернете, так и на нашем сайте. Но иногда разработчикам приходится сталкиваться с закрытыми web-сервисами SOAP, требующих авторизации. Поскольку это не тривиальная задача, и, если учесть, что приходится заниматься ей от случая к случаю, то было решено также и на нашем сайте оставить следы её реализации. Данная статья является продолжением описания SOAP клиента, представленного на сайте, с тем отличием, что здесь будет рассмотрен аспект авторизованного подключения к WEB-сервису. Попробуем представить постановку задачи, поступившей от «серьезного» Заказчика (реальная) : Поскольку уже для Заказчика создано несколько приложений с использованием очередей MQ, то не стали упираться и решили расширить область используемых технологий, разрабатывая SOAP клиента с авторизацией. Сначала необходимо набросать небольшой код для определения требуемых параметров SOAP клиента, которые должен предоставить Заказчик : import javax.xml.soap.*; // URL WEB-сервисов private String urlSummer = "http://99.99.99.99:999/service/summer"; private String urlWinter = "http://99.99.99.99:999/service/winter"; private String namespace = "..."; private String targetNamespace = "..."; // Параметры авторизации private String login = "guest"; private String password = "service"; // Наименования WEB-сервисов private String svcSummer = "summer"; private String svcWinter = "winter"; //----------------------------------------- // Производные параметры WEB-сервиса private String soapUrl = null; private String serviceName = null; private String soapAction = null; /* * Флаг использования одного из сервисов : * если true, то сервис summer, в противном случае winter */ private boolean SERVICE_summer = true; //------------------------------------------------------------------- private void setSoapParams() { soapUrl = SERVICE_xxx ? urlSummer : urlWinter; serviceName = SERVICE_xxx ? svcSummer : svcWinter; soapAction = targetNamespace + "/" + serviceName; } Итак, для использования 2-х закрытых WEB-сервисов необходим их URL (urlSummer, urlWinter), наименование namespace, targetNamespace и параметры авторизации. На этапе отладки в процедуре setSoapParams определяются параметры подключения к одному определенному web-сервису. Получили от Заказчика всё за исключением namspace и targetNamespace; наименование web-сервисов извлекли из URL. Чтобы получить отсутствующие два параметра дополнительно запросили WSDL сервисов, в которых их можно найти : <?xml version="1.0" encoding="UTF-8"?> <definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xxx="http://xxxxx-xx.com/xxx" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://xxxxx-xx.com/xxx" name="summer"> <!-- SOAP 1.1 WSDL - dynamically generated by XXX. --> <types> . . . </types> <message name="exportRequestMsg"> . . . </message> <message name="exportResponseMsg"> . . . </message> <message name="exportExceptionMsg"> <part name="fault" element="xxx:AIMSoapExportException"/> </message> <portType name="summerImpl"> . . . </portType> <binding name="summerPortBinding" type="xxx:summerImpl"> . . . </binding> <service name="summer"> . . . </service> </definitions> Наименование namespace (xmlns:xxx) и targetNamespace ( http://xxxxx-xx.com/xxx ) включены в качестве атрибутов в тег описания сервиса <definitions>. Подставляем их значения в переменные определения (код в начале). Ну а остальное дело техники. Пишем процедуры формирования SOAP сообщения, SOAP запроса и обращения к WEB-сервису. Процедура формирования тела SOAPMessageПроцедура createSoapEnvelope в качестве параметра получает значение типа SOAPMessage. В теле процедуры определяются namespace, targetNamespace (метод addNamespaceDeclaration) и формируется тело сообщения soapBody, которое может быть намного сложнее, чем это представлено в коде, и включать определенные параметры запроса к SOAP-сервису. private void createSoapEnvelope(SOAPMessage soapMessage) throws SOAPException { SOAPPart soapPart = soapMessage.getSOAPPart(); // SOAP Envelope SOAPEnvelope envelope = soapPart.getEnvelope(); envelope.addNamespaceDeclaration(namespace, targetNamespace); // SOAP Body SOAPBody soapBody = envelope.getBody(); soapBody.addChildElement(serviceName, namespace); } Процедура создания SOAPMessage с авторизациейВ процедуре createSOAPRequest создается объект SOAPMessage. В заголовочную часть SOAP сообщения вставляются описания SOAPAction и кодированное значение параметров авторизации 'auth' в формате «login:password». Для кодирования строки «login:password» используется кодировщик утилиты java.util.Base64. В заголовок SOAP сообщения параметры авторизации добавляются в кодированном виде с ключом «Authorization»; кодированное значение 'auth' добавляется с префиксом "Basic ", от которого оно отделено символом пробела. Текст сформированного SOAP сообщения выводится в консоль (без отображения заголовка). 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); // Определение авторизации сервиса String loginPassword = login + ":" + password; byte[] bytes = loginPassword.getBytes(); String auth = new String(Base64.getMimeEncoder().encode(bytes)); headers.addHeader("Authorization", "Basic " + auth); soapMessage.saveChanges(); // Печать XML текста запроса в консоль soapMessage.writeTo(System.out); System.out.println("\n"); return soapMessage; } Процедура вызова сервисаПроцедура callSoapWebService включает вызовы всех вышеописанных процедур для формирования и оправки SOAP запроса и получения от WEB-сервиса ответа. Сначала определяются параметры WEB-сервиса, после этого формируется запрос soapRequest. Для подключения к WEB-сервису создается SOAPConnection, который в качестве параметров получает запрос soapRequest и soapUrl. Объект подключения soapConnect возвращает от сервиса ответ soapResponse типа SOAPMessage, который, в зависимости от формата, можно ковертировать либо в XML, либо в JSON. В процедуре parseSOAPResponse ответ сервиса soapResponse переводится в текстовый вид. private void callSoapWebService() { SOAPConnectionFactory soapFactory = null; SOAPConnection soapConnect = null; SOAPMessage soapRequest = null; SOAPMessage soapResponse = null; try { // Определение параметров сервиса setSoapParams(); // Создание SOAP Message для отправки soapRequest = createSOAPRequest(soapAction); // Создание SOAP Connection soapFactory = SOAPConnectionFactory.newInstance(); soapConnect = soapFactory.createConnection(); // Получение SOAP Message soapResponse = soapConnect.call(soapRequest, soapUrl); // Разложение SOAP Response parseSOAPResponse (soapResponse); soapConnect.close(); } catch (Exception e) { System.err.println("Exception : " + e.getMessage()); } } Процедура обработки ответаОтвет WEB-сервиса типа SOAPMessage конвертируется в процедуре parseSOAPResponse сначала в текстовый вид с использованием потока ByteArrayOutputStream. Далее, в зависимости от формата ответа и цели обращения к сервису, ответ может быть преобразован в XML, JSON и т.д. private void parseSOAPResponse (SOAPMessage soapResponse) { try { // Получение содержимого ответа ByteArrayOutputStream stream = new ByteArrayOutputStream(); soapResponse.writeTo(stream); String content = new String(stream.toByteArray(), "utf-8"); System.out.println(content); // ... } catch (Exception e) { System.err.println("Exception : " + e.getMessage()); } } Листинг примераПредставленные выше листинги процедур были извлечены из примера SoapClientExample. Вы можете их использовать по собственному усмотрению с внесением необходимых доработок. Полагаю Вам не составит особого труда весь описанный выше код в виде полей и процедур вставить в класс SoapClientExample, чтобы получить завершенный пример. import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.StringReader; import java.util.Base64; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.soap.*; import org.w3c.dom.Document; import org.xml.sax.InputSource; import org.xml.sax.SAXException; public class SoapClientExample { . . . //--------------------------------------------------------------- public SoapClientExample() { callSoapWebService(); } //--------------------------------------------------------------- public static void main(String[] args) { new SoapClientExample(); System.exit(0); } } |