IBM®
Перейти к тексту
    в России и странах СНГ [изменить]    Условия использования
 
 
   
    Главная страница    Продукты    Услуги и решения    Поддержка и загрузка    Мой профиль    
Перейти к тексту

developerWorks Россия  >  XML | SOA и Web-сервисы  >

Совет: Отправка и получение сообщений SOAP с помощью SAAJ

Программный интерфейс для Java позволяет автоматизировать множество шагов, необходимых при ручном создании и отправке сообщений

developerWorks
Опции документа

Опции документа, требующие включения JavaScript, не отображаются


Выскажите мнение об этой странице

Помогите нам улучшить содержание


Уровень сложности: средний

Никлас Чейз, Независимый автор, Backstop Media

08.05.2009

В этой статье-совете автор и разработчик Николас Чейз расскажет об использовании программного интерфейса Java для сообщений SOAP с вложениями (SOAP with Attachments API for Java). Интерфейс позволяет упростить процесс создания и отправки сообщений SOAP.

Возможность отправки и получения сообщения в стандартном формате, распознаваемом всеми взаимодействующими системами, лежит в основе технологии Web-сервисов. Как правило, этим форматом является SOAP. Сообщения SOAP можно создавать и отправлять вручную, но многие из необходимых шагов, например установка соединения или отправка сообщения, могут быть выполнены автоматически с помощью SAAJ (SOAP with Attachments API for Java) – API, появившегося в результате работы над программным интерфейсом для передачи сообщений XML (Java API for XML Messaging - JAXM). В данной статье рассматривается последовательность действий по созданию и отправке синхронных сообщений SOAP.

Весь процесс состоит из пяти шагов:

  1. создание соединения SOAP;
  2. создание сообщения SOAP;
  3. формирование сообщения;
  4. отправка сообщения;
  5. получение ответа.

SAAJ поставляется в составе пакета для разработки Web-сервисов Java (Java Web Services Developer Pack 1.2, см. Ресурсы). В пакет включены также Web-сервер Tomcat, благодаря которому вы можете развернуть собственный Web-сервис, и демонстрационные приложения.

Установка

Установка и конфигурирование Java Web Services Developer Pack 1.2 не представляет трудностей, если вы собираетесь отправлять сообщения через Web-сервер Tomcat. Если же подобно тому, как это делается в данной статье, вы хотите отправлять сообщения через отдельное приложение, то потребуются некоторые дополнительные действия.

  1. Скачайте JWSDP 1.2 по адресу: http://java.sun.com/webservices/downloads/webservicespack.html.
  2. Установите его согласно инструкциям.
  3. Если вы используете Java 1.4, то вам следует переопределить классы, относящиеся к XML, которые входят в поставку JWSDP 1.2. Создайте следующую директорию:
    <JAVA_HOME>/jre/lib/endorsed
    и скопируйте в нее все файлы из:
    <JWSDP_HOME>/jaxp/lib/endorsed
    (переменные окружения JAVA_HOME и JWSDP_HOME указывают на директории установки Java и JWSDP соответственно).
  4. Добавьте следующие файлы в classpath:
    • <JWSDP_HOME>/saaj/lib/saaj-api.jar
    • <JWSDP_HOME>/saaj/lib/saaj-impl.jar
    • <JWSDP_HOME>/jwsdp-shared/lib/commons-logging.jar
    • <JWSDP_HOME>/jwsdp-shared/lib/mail.jar
    • <JWSDP_HOME>/jwsdp-shared/lib/activation.jar
    • <JWSDP_HOME>/jaxp/lib/endorsed/dom.jar
    • <JWSDP_HOME>/jaxp/lib/endorsed/xercesImpl.jar
    • <JWSDP_HOME>/jaxp/lib/endorsed/sax.jar
    • <JWSDP_HOME>/jaxp/lib/endorsed/xalan.jar

Теперь вы можете посылать сообщения из любой точки в вашей системе, используя собственное приложение.



В начало


Структура сообщения SOAP

Начнем с рассмотрения структуры самих сообщений. В общем случае SOAP-сообщение состоит из оболочки, разделенной на две главные части: заголовок и само сообщение. Несмотря на то, что использование этих частей остается на усмотрение конкретного приложения, сообщения должны иметь определенную XML-структуру, подобную показанной в листинге 1.


Листинг 1. Пример сообщения SOAP
        
        <SOAP-ENV:Envelope 
        xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
        xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" 
        xmlns:xsd="http://www.w3.org/1999/XMLSchema"> 
    <SOAP-ENV:Header />
    <SOAP-ENV:Body> 
        <ns1:getPrice xmlns:ns1="urn:xmethods-BNPriceCheck" 
             SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> 
                  <isbn xsi:type="xsd:string">0672324229</isbn> 
        </ns1:getPrice> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

В этом примере заголовок является пустым, и вся полезная часть заключена в теле сообщения. Данное сообщение используется для запроса цены на книгу.

Обратите внимание на структуру сообщения. Оболочка (элемент Envelope) содержит элементы Header и Body, причем все три принадлежат пространству имен http://schemas.xmlsoap.org/soap/envelope/. Приложение отправляет сообщения, используя объект SOAPConnection.



В начало


Установка соединения и создание сообщения

Первым шагом является создание экземпляра класса соединения и установка самого соединения (листинг 2).


Листинг 2. Создание соединения
        import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPConnection;

public class SOAPTip {
    
   public static void main(String args[]) {
        
      try {
      
         //Сначала создаем соединение
         SOAPConnectionFactory soapConnFactory = 
                            SOAPConnectionFactory.newInstance();
         SOAPConnection connection = 
                             soapConnFactory.createConnection();
         


         //Закрываем соединение            
         connection.close();
            
        } catch(Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

Приложение может отправлять сообщения SOAP непосредственно через класс SOAPConnection, который теперь включен в пакет SAAJ, или с использованием провайдера сообщений, являющегося частью пакета JAXM. Объект SOAPConnection создается с помощью фабрики.

Фабрика также используется для создания самого сообщения (листинг 3).


Листинг 3. Создание сообщения
        import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPBody;

public class SOAPTip {
    
   public static void main(String args[]) {
        
      try {
     
         //Сначала создаем соединение
         SOAPConnectionFactory soapConnFactory = 
                            SOAPConnectionFactory.newInstance();
         SOAPConnection connection = 
                             soapConnFactory.createConnection();
         
         //Затем создаем сообщение
         MessageFactory messageFactory = MessageFactory.newInstance();
         SOAPMessage message = messageFactory.createMessage();
         
         //Создаем объекты, представляющие различные компоненты сообщения        
         SOAPPart soapPart =     message.getSOAPPart();
         SOAPEnvelope envelope = soapPart.getEnvelope();
         SOAPBody body =         envelope.getBody();


         //Закрываем соединение
         connection.close();
            
        } catch(Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

Различия между версиями
Если вы используете другую версию SAAJ, например библиотеку, входящую в состав Axis 1.2, то, возможно, вам следует вызывать метод addBodyElement вместо addChildElement.

Сначала с помощью объекта MessageFactory создается собственно сообщение. В этот момент оно уже включает в себя разделы envelope и header, но они пока пусты. Объект SOAPPart содержит envelope, в который, в свою очередь, включено тело сообщения. Далее объявляются переменные, содержащие все необходимые ссылки, в частности, SOAPBody.

Далее необходимо заполнить данными тело сообщения (объект SOAPBody), как показано в листинге 4.


Листинг 4. Формирование тела сообщения
        ...
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPElement;

public class SOAPTip {
    
   public static void main(String args[]) {
        
      try {
...
         //Создание объектов, представляющих собой части сообщения 
         SOAPPart soapPart =     message.getSOAPPart();
         SOAPEnvelope envelope = soapPart.getEnvelope();
         SOAPBody body =         envelope.getBody();

        //Формирование тела сообщения
        //Создание главного элемента с учетом пространства имен
        SOAPElement bodyElement = 
                  body.addChildElement(envelope.createName("getPrice" , 
                                                                "ns1", 
                                          "urn:xmethods-BNPriceCheck"));
        //Добавление содержимого
        bodyElement.addChildElement("isbn").addTextNode("0672324229");

        //Сохранение сообщения
        message.saveChanges();


        //Проверка созданного сообщения
        System.out.println("\nREQUEST:\n");
        message.writeTo(System.out);
        System.out.println();


         //Закрытие соединения
         connection.close();
            
        } catch(Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

Тело сообщения SOAP представляет собой обыкновенный XML-элемент, в который можно помещать вложенные элементы, такие как getPrice. Далее можно добавить элемент isbn и соответствующий ему текст. Все делается так же, как и в случае любого элемента DOM.

SAAJ также позволяет напрямую создать объект SOAPPart-сообщения из внешнего файла. Например, если XML-содержимое сообщения, приведенного в листинге 1, содержится в файле prepped.msg, то к нему можно обратиться вместо ручного создания сообщения (листинг 5).


Листинг 5. Создание сообщения из внешнего файла
        ...
import javax.xml.soap.SOAPElement;

import java.io.FileInputStream;
import javax.xml.transform.stream.StreamSource;

public class SOAPTip {
    
   public static void main(String args[]) {
...
         //Создание объектов, представляющих различные части сообщения      
         SOAPPart soapPart =     message.getSOAPPart();
         SOAPEnvelope envelope = soapPart.getEnvelope();
         SOAPBody body =         envelope.getBody();

         //Формирование сообщения
        StreamSource preppedMsgSrc = new StreamSource( 
                 new FileInputStream("prepped.msg"));
        soapPart.setContent(preppedMsgSrc);

         //Сохранение сообщения
         message.saveChanges();
...
    }
}

Класс StreamSource обычно используется при преобразованиях XSL, но в данном случае с его помощью просто открывается файловый поток ввода FileInputStream. В результате у нас получилось готовое к отправке сообщение.



В начало


Отправка сообщения

При работе с синхронными сообщениями SOAP, отправка и получение ответа выполняются за один шаг (листинг 6).


Листинг 6. Отправка сообщения
        ...
public class SOAPTip {
    
   public static void main(String args[]) {
        
...
         //Проверка созданного сообщения
         System.out.println("\nREQUEST:\n");
         message.writeTo(System.out);
         System.out.println();

        //Отправка сообщения и получение ответа
            
        //Установка адресата
        String destination = 
            "http://services.xmethods.net:80/soap/servlet/rpcrouter";
        //Отправка
        SOAPMessage reply = connection.call(message, destination);

         //Закрытие соединения
         connection.close();         
...
    }
}

Заголовок SOAPAction

Некоторые Web-сервисы могут вернуть ошибку, потребовав наличия в сообщении заголовка SOAPAction, который используется для идентификации сервиса. Это можно сделать, задав требуемое значение в объекте MIMEHeaders следующим образом:

MimeHeaders headers = message.getMimeHeaders();
headers.addHeader("SOAPAction", "urn:requiredSOAPAction");

Сообщение отправляется в момент вызова метода call(), который принимает в качестве аргументов само сообщение и адрес назначения. В качестве ответа метод возвращает другой объект SOAPMessage. В более ранних версиях JAXM адрес назначения должен был быть экземпляром класса Endpoint или URLEndpoint, но в текущей версии адресом может быть объект любого типа. В данном примере используется Web-сервис под названием "Узнай цену на книгу" ("Book price checker"), размещенный на сервере XMethods и возвращающий цену на книгу, ISBN которой содержится в запросе.

Метод call() блокирует выполнение программы до момента получения ответа в виде объекта SOAPMessage.



В начало


Ответ

Полученный объект типа SOAPMessage, ссылка на который хранится в переменной reply, также является сообщением SOAP, и его структура идентична отправленному сообщению. Как и любое XML-сообщение, его можно трансформировать с помощью XSLT. SOAP позволяет выполнить XSLT-преобразование напрямую, как показано в листинге 7.


Листинг 7. Чтение полученного ответа
        ...
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.Source;

import javax.xml.transform.stream.StreamResult;

public class SOAPTip {
    
   public static void main(String args[]) {
        
      try {
      
...
         //Отправка сообщения
         SOAPMessage reply = connection.call(message, destination);

        //Проверка полученного ответа
        System.out.println("\nRESPONSE:\n");
        //Создание XSLT-процессора
        TransformerFactory transformerFactory = 
                           TransformerFactory.newInstance();
        Transformer transformer = 
                        transformerFactory.newTransformer();
        //Получение содержимого ответа
        Source sourceContent = reply.getSOAPPart().getContent();
        //Задание выходного потока для результата преобразования
        StreamResult result = new StreamResult(System.out);
        transformer.transform(sourceContent, result);
        System.out.println();

         //Закрытие соединения
         connection.close();
...            
     }
}

Сначала, как и всегда при использовании XSLT, необходимо создать объект Transformer. В данном случае нам просто надо вывести содержимое сообщения, поэтому таблица стилей не используется. Под содержимым понимается SOAP-часть сообщения, а не все сообщение, в котором могут еще содержаться вложения. Перед обработкой можно также разделить оболочку и тело сообщения. Содержимое выводится в System.out (см. рисунок 1), но в принципе результат трансформирования может выводиться в любой доступный поток вывода. Само преобразование происходит обычным образом.


Рисунок 1. Запрос и ответ в SOAP
Request and response


В начало


Следующие шаги

В нашем простом примере сообщение просто выводится в стандартный поток вывода, но с таким же успехом можно было получить нужную информацию из документа XML. Кроме того, хотя в данной статье демонстрируется синхронная отправка и получение сообщений, интерфейс JAXM, который можно скачать отдельно, позволяет использовать провайдер сообщений, обеспечивающий асинхронную доставку с помощью объекта ProviderConnection вместо SOAPConnection. Провайдер хранит сообщение, пока оно не будет успешно доставлено.

JAXM также поддерживает работу с профилями, которые облегчают создание специализированных сообщений SOAP, таких как SOAP-RP или ebXML.



Ресурсы



Об авторе

Никлас Чейз (Nicholas Chase) участвовал в разработке Web-сайтов для таких компаний, как Lucent Technologies, Sun Microsystems, Oracle и Tampa Bay Buccaneers. Ник успел побывать школьным учителем физики, редактором электронного научно-фантастического журнала, инженером в области мультимедиа, инструктором по Oracle и главным инженером в интерактивной коммуникационной компании. Он является автором нескольких книг, в том числе XML Primer Plus (Sams).




Выскажите мнение об этой странице


Пожалуйста, найдите минутку и заполните форму, чтобы повысить уровень сервиса.



 


 


 


Поделиться этой статьей:

забобрить забобрить memori сохранить в memori




В начало


IBM обладает всеми авторскими правами касательно информации, расположенной на developerWorks. Использование информации приведенной на этом ресурсе без явного письменного разрешения от IBM или первоначального автора запрещены. Если Вы желаете использовать информацию с developerWorks, пожалуйста воспользуйтесь регистрационной формой для того, чтобы связаться с нами запрос на использование материалов developerWorks Россия.
    IBM в России Конфиденциальность Контакты