Перейти к тексту

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

При первом входе в developerWorks для Вас будет создан профиль. Выберите информацию отображаемую в Вашем профиле — скрыть или отобразить поля можно в любой момент.

Вся введенная информация защищена.

  • Закрыть [x]

При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

Вся введенная информация защищена.

  • Закрыть [x]

Передача файлов в Web-сервис

SOAP и бинарные данные

Бёнуа Маршаль, консультант, Pineapplesoft
Бёнуа Маршаль (Benoît Marchal) – бельгийский консультант. Он автор многих книг, посвященных XML, в том числе «XML на примерах, второе издание» XML by Example, Second EditionБёнуа Маршаль специализируется в области XML, технологий Java и электронной коммерции. Более подробную информацию о нем можно получить на его сайте www.marchal.com. С ним можно связаться по адресу bmarchal@pineapplesoft.com.

Описание:  В этой статье ведущий колонки «Совет» (Tip) рассматривает различные подходы, используемые для передачи бинарных данных (обычно файлов) Web-сервис.

Дата:  23.03.2007
Уровень сложности:  средний
Активность:  4025 просмотров
Комментарии:  


В своем развитии протоколы Web-сервисов прошли долгий путь, начиная поддержкой очень простых запросов с несложными параметрами и заканчивая полной поддержкой современных объектно-ориентированных языков. Спецификация XML-RPC (Удаленный вызов процедуры на XML), являющаяся, пожалуй, одной из самых ранних форм Web-сервисов, поддерживала только простые типы – строки, целые числа, логические выражения и т.п. Следующим шагом явилось появление в SOAP правил кодирования для объектов. Наконец, последний шаг – улучшение бинарного кода - было введено в документе консорциума W3C "SOAP с вложениями" (SOAP with attachments).

Первоначально "SOAP с вложениями" был предложен в качестве расширения SOAP 1.1, и сегодня эта технология поддерживается в большинстве инструментальных средств SOAP. Несмотря на то, что вложения пока не поддерживаются в официальной версии спецификации W3C SOAP 1.2, в настоящий момент ведутся работы с целью их включения в этот документ в (умозрительно) ближайшем будущем.

Web-сервис и бинарные данные

Автор не испытывает ни малейших сомнений в том, что успех XML для решения задач интеграции приложений связан с использованием текстового кодирования (как противопоставления бинарным протоколам, как, например, CORBA, объектно-ориентированному стандарту RPC, или RMI, основанному на Java стандарту RPC). Текстовое кодирование предпочтительно по нескольким причинам, наиболее значимая из которых заключается в том, что в случае необходимости упрощается отладка и развертывание конкретного приложении.

И все же использование текстового кодирования имеет и свои «темные стороны», а XML не располагает действенным способом включения бинарных данных. Согласно рекомендации консорциума W3C «XML-схема» (W3C XML Schema), бинарные данные должен быть закодированы с использованием кода Base-64 или шестнадцатеричного кода. К сожалению, размер данных, закодированных с помощью шестибитного кода (Base-64), оказывается в полтора раза больше по сравнению с размером незакодированных данных. Размер данных, преобразованных в систему счисления с основанием 16, оказывается в два раза больше исходного. Такие накладные расходы приемлемы в случае небольших фрагментов бинарных данных, но для больших наборов данных такой подход неприемлем.

Вместе с тем бинарные данные удобны для многих приложений, например:

  • Для систем обеспечения безопасности необходимы ключи, знаки "решетка", сертификаты, сами закодированные данные.
  • Мультимедийные приложения используют фото, музыку и фильмы.
  • В некоторых приложениях применение XML-представления оказывается неэффективным, например, в случае автоматизированного проектирования (CAD) или автоматизированного производства (CAM).
  • Существуют тысячи файловых форматов, которые появились до XML – форматы текстовых процессоров, электронных таблиц, шрифтов, векторной графики и т.д.

Хотя создание XML-версий этих файловых форматов возможно (аналогично формату SVG (Scalable Vector Graphics, масштабируемая векторная графика) для векторной графики), бинарные данные существуют уже давно и вряд ли потеряют популярность.

Наконец, существуют проблемы и с самим XML! Например, включение одного XML-документа в другой XML-документ не является тривиальной задачей (синтаксически корректное решение опирается на разделы CDATA и переход на другие символы).

MIME и код base 64

Чтобы избежать часто возникающие недоразумения, подчеркнем, что MIME не требует обязательного использования кодирования base 64. Точнее реализации HTTP не кодируют включения; их кодируют только почтовые клиенты, чтобы обойти ограничения SMTP (поэтому при сравнении с XML каких-либо преимущества отсутствуют).

Поэтому, чтобы реализовать требования всех этих приложений, Web-сервисы должны эффективно поддерживать бинарные данные. Предлагаемое решение – SOAP с вложениями, который, если попытаться сказать кратко, удаляет бинарную информацию из полезной нагрузки XML и сохраняет ее непосредственно в запросе HTTP в качестве содержания MIME multipart/related.

Таким образом, при проектировании Web-сервиса, который использует бинарные данные, следует воспользоваться один из следующих подходов:

  • Если набор данных невелик, можно использовать код Base-64 для полезной нагрузки XML; накладные расходы для небольших фрагментов данных не являются серьезной проблемой.
  • Если набор данных значителен, включение – единственный практически разумный выбор.

Ниже приведен Листинг 1 (запрос SOAP с параметром, закодированным с помощью шестибитного кода, в котором особого внимания заслуживает элемент address.


Листинг 1. Параметр в системе счисления с основанием 64r
POST /ws/retrieve HTTP/1.0
Content-Type: text/xml; charset=utf-8
Accept: application/soap+xml multipart/related, text/*
Host: localhost:8080
SOAPAction: ""
Content-Length: 540

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
  <ps:retrieve 
           soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
           xmlns:ps="http://psol.com/2004/ws/retrieve">
   <address xsi:type="xsd:base64Binary">d3d3Lm1hcmNoYWwuY29t</address>
  </ps:retrieve>
 </soapenv:Body>
</soapenv:Envelope>


Реализация включений

Разработчики Java могут воспользоваться включениями, используя JAX-RPC (API на Java для RPC, основанного на XML) и SAAJ (API SOAP с включениями для Java). Читателю следует обратить внимание на аббревиатуру SAAJ: JAX-RPC поддерживает включения (см., например, Resources). Различие между JAX-RPC и SAAJ заключается в уровне абстракции, а не в функциональных возможностях.

JAX-RPC – это API высокого уровня, он более абстрактен по сравнению с SAAJ. JAX-RPC скрывает за слоем протокола RMI (Remote Method Invocation, технология построения распределенных приложений в спецификации языка Java) большинство ориентированных на протокол аспектов SOAP. Разработчик занимается объектами Java, а препроцессор превращает их в узлы SOAP. Для представления включений JAX-RPC использует классы java.awt.Image и javax.activation.DataHandler.

SAAJ более близок к протоколу. Поскольку для создания SOAP-сообщений с помощью SAAJ требуется больше усилий, чем с JAX-RPC (и, следовательно, он не предоставляет автоматических связей с WSDL), в большинстве случае читатель отдаст предпочтение JAX-RPC. Вместе с тем, низкоуровневые аспекты более удобны для иллюстрации того, как на самом деле работают включения. Листинг 2 – это запрос SOAP с включением. Этот запрос просит сервер изменить размер фотографии; поскольку размер файла фотографии велик, использование включения более предпочтительно.


Листинг 2. Параметр включения
POST /ws/resize HTTP/1.0
Content-Type: multipart/related; type="text/xml"; 
     start="<EB6FC7EDE9EF4E510F641C481A9FF1F3>"; 
     boundary="----=_Part_0_7145370.1075485514903"
Accept: application/soap+xml, multipart/related, text/*
Host: localhost:8080
SOAPAction: ""
Content-Length: 1506005

------=_Part_0_7145370.1075485514903
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: binary
Content-Id: <EB6FC7EDE9EF4E510F641C481A9FF1F3>

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
                  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
  <ps:resize 
          soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
          xmlns:ps="http://psol.com/2004/ws/resize" 
          xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
   <source href="cid:E1A97E9D40359F85CA19D1B8A7C52AA3"/>
   <percent>20</percent>
  </ps:resize>
 </soapenv:Body>
</soapenv:Envelope>

------=_Part_0_7145370.1075485514903
Content-Type: image/jpeg
Content-Transfer-Encoding: binary
Content-Id: <E1A97E9D40359F85CA19D1B8A7C52AA3>

note: binary data deleted...

------=_Part_0_7145370.1075485514903--

Приведенный ниже Листинг 3 демонстрирует создание запроса SOAP. Этот запрос просит сервер изменить размер изображения. Для реализации этой процедуры необходимо выполнить следующую последовательность действий:

  • Создать соединение SOAP и объекты сообщения SOAP через фабрики (factories).
  • Извлечь тело сообщения из объекта сообщения (промежуточный шаг: извлечь часть (part) SOAP и конверт).
  • Создать новый XML-элемент для представления запроса и установить стиль кодирования.
  • Создать включение и инициализировать его с объектом DataHandler.
  • Создать еще элементы для представления двух параметров (source и percent).
  • Ассоциировать включение с первым параметром посредством добавления атрибута href. Ссылка на это включение осуществляется через универсальный локатор ресурса cid (content-id).
  • Задать значение второго параметра непосредственно в виде текста и вызвать сервис.

Сервис предоставляет ответ с изображением, размеры которого изменены, причем это изображение представлено в виде включения. Чтобы извлечь его, можно протестировать SOAP на предмет неисправности (т.е. ошибки). Если неисправностей нет, включение следует извлечь в виде файла, а затем обработать.


Листинг 3. Использование SAAJ
public File resize(String endPoint,File file)
{
   SOAPConnection connection =
      SOAPConnectionFactory.newInstance().createConnection();
   SOAPMessage message = MessageFactory.newInstance().createMessage();
   SOAPPart part = message.getSOAPPart();
   SOAPEnvelope envelope = part.getEnvelope();
   SOAPBody body = envelope.getBody();
   SOAPBodyElement operation =
      body.addBodyElement(
         envelope.createName("resize",
                             "ps",
                             "http://psol.com/2004/ws/resize"));
   operation.setEncodingStyle("http://schemas.xmlsoap.org/soap/encoding/");

   DataHandler dh = new DataHandler(new FileDataSource(file));
   AttachmentPart attachment = message.createAttachmentPart(dh);
   SOAPElement source = operation.addChildElement("source",""),
               percent = operation.addChildElement("percent","");
   message.addAttachmentPart(attachment);
   source.addAttribute(envelope.createName("href"),
                       "cid:" + attachment.getContentId());
   width.addTextNode("20");

   SOAPMessage result = connection.call(message,endPoint);
   part = result.getSOAPPart();
   envelope = part.getEnvelope();
   body = envelope.getBody();
   if(!body.hasFault())
   {
      Iterator iterator = result.getAttachments();
      if(iterator.hasNext())
      {
         dh = ((AttachmentPart)iterator.next()).getDataHandler();
         String fname = dh.getName();
         if(null != fname)
            return new File(fname);
      }
   }
   return null;
}

Стоит обратить внимание на то, что в Листинге 3 включение находится вне XML-сообщения. Такой подход повышает производительность.

Говоря о производительности, рассмотрим Листинг 4, в котором показана более общая (и существенно более короткая) версия JAX-RPC Листинга 3. Прекомпилятор JAX-RPC генерирует переходник (stub), которая значительно упрощает кодирование. В этом случае в качестве параметра метода передается объект DataHandler, а JAX-RPC автоматически генерирует это включение.


Листинг 4. Более эффективный JAX-RPC
public File resize(File file)
   throws ServiceException, RemoteException
{
   AttachmentService service = new AttachmentServiceLocator();
   AttachmentTip port = service.getAttachmentTip();   // get stub
   DataHandler dh = new DataHandler(new FileDataSource(file));
   DataHandler result = port.resize(dh,20);
   return new File(result.getName());
}


Заключение

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


Ресурсы

  • Примите участие в обсуждении материала на форуме.

  • Tip: Passing files to a Web service Оригинал статьи

  • Форумпосвященный обсуждению статей в колонке Беноита Марчала (Benoît Marchal) “XML в действии” (Working XML).

  • Для изучения SAAJ и JAX-RPC можно скачать Axis Необходимо отметить, что для работы с включениями читателю потребуется установить два дополнительных компонента:JavaMail и JavaBeans Activation Framework. Автор хотел бы подчеркнуть, что включения не работают в Axos (версии 1.1 и 1.2), если эти две компоненты не установлены.

  • Международный консорциум W3C ведет работы над поддержкой вложений в SOAP 1.2 attachment support to SOAP 1.2.

  • Статья Рассела Бутека (Russell Butek) «Отправка и получение сообщений SOAP с JAX-RPC» Send and receive SOAP messages with JAX-RPC (developerWorks, сентябрь 2003 г.).

  • В своей статье «Преобразование типов Apache SOAP» Apache SOAP type mapping Гевин Бонг (Gavin Bong) рассматривает соответствие между SOAP и технологией Java. Несмотря на то, что этот материал написан с позиции Apache SOAP, он применим и к большинству инструментальных средств SOAP (developerWorks, апрель 2002 г.).

  • Ранняя версия (6.0) сервера приложений IBM WebSphere IBM WebSphere Application Server Technology for Developers, version 6.0, поддерживающего последнюю редакцию спецификации J2EE (версию 1.4).

  • Множество других ресурсов в зоне XML zone рубрики developerWorks.

  • На странице Web services/XML Tips newsletterможно подписаться на еженедельную рассылку новостей рубрики developerWorks.

  • На странице IBM Certified Developer in XML and related technologies приведена информация о том, как стать сертифицированным разработчиком XML.

Об авторе

Бёнуа Маршаль (Benoît Marchal) – бельгийский консультант. Он автор многих книг, посвященных XML, в том числе «XML на примерах, второе издание» XML by Example, Second EditionБёнуа Маршаль специализируется в области XML, технологий Java и электронной коммерции. Более подробную информацию о нем можно получить на его сайте www.marchal.com. С ним можно связаться по адресу bmarchal@pineapplesoft.com.

Помощь по сообщениям о нарушениях

Сообщение о нарушениях

Спасибо. Эта запись была помечена для модератора.


Помощь по сообщениям о нарушениях

Сообщение о нарушениях

Сообщение о нарушении не было отправлено. Попробуйте, пожалуйста, позже.


developerWorks: вход


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


При первом входе в developerWorks для Вас будет создан профиль. Выберите информацию отображаемую в Вашем профиле — скрыть или отобразить поля можно в любой момент.

Выберите ваше отображаемое имя

При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

(Должно содержать от 3 до 31 символа.)


Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Оценить эту статью

Комментарии

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=XML, SOA и Web-сервисы
ArticleID=203950
ArticleTitle=Передача файлов в Web-сервис
publish-date=03232007
author1-email=bmarchal@pineapplesoft.com
author1-email-cc=

Теги

Help
Используйте форму поиска, чтобы найти любой контент с данным тегом в My developerWorks. Используйте ползунок, чтобы отразить больше или меньше тегов.

КнопкаПопулярные теги отображает самые распространенные теги для данной области контента (например: Java, Linux, WebSphere).

Кнопка Мои теги отображает Ваши теги для данной области контента (например: Java, Linux, WebSphere).

Используйте форму поиска, чтобы найти любой контент с данным тегом в My developerWorks. Кнопка Популярные теги отображает самые распространенные теги для данной области контента (например: Java, Linux, WebSphere). Кнопка Мои теги отображает Ваши теги для данной области контента (например: Java, Linux, WebSphere).