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);
}
}
|
