XML для веб-службы: встроенное вложение - PullRequest
2 голосов
/ 02 апреля 2009

Мне нужно вызвать веб-сервис с одним параметром - строкой в ​​формате XML. Я строю это с помощью XSLT-преобразования. Все идет нормально.

Проблема с этим XSD-фрагментом:

<xs:complexType name="Document">
    <xs:sequence>
        <xs:element name="title" type="xs:string" minOccurs="1"/>
        <xs:element name="content" type="xs:base64Binary" minOccurs="1"/>
    </xs:sequence>
</xs:complexType>

который переводит (например) в этот XML:

<attachment>
    <title>test title</title>
    <content>          
    PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Inllc
    yI/Pg0KPG1zZ3ByYXRpY2E+DQogICAgPHByYXRpY2E+DQogICAgICAgIDxwcm9jZXNzbz
    4NCiAgICAgICAgICAgIDxjb2RQcm9jZXNzbz4xPC9jb2RQcm9jZXNzbz4NCiAgICAgICA
    gICAgIDxjb2RJc3RhbnphUHJvY2Vzc28MzwvY29kSXN0YW56YVByb2Nlc3NvPg0KICAgI
    CAgICAgICAgPGNvZFN0YXRvPjYwPC9jb2RTdGF0bz4NCiAgICAgICAgPC9wcm9jZXNzbz
    4NCiAgICA8L3ByYXRpY2E+DQo8L21zZ3ByYXRpY2E+
    </content>
</attachment>

Да, вы правильно поняли: мне нужно вставить содержимое файла в документ XML в двоичном формате base 64.

Я думал о том, чтобы вставить заполнитель с XSLT, а затем обработать XML-документ, чтобы заменить его фактическим содержимым файла, но мне интересно, есть ли какие-либо лучшие практики для этих случаев, может быть, какой-то причудливый трюк с XSTL выходит далеко за рамки моих знаний или некоторые инструменты Java, которые могут пригодиться.

Как бы вы это сделали?

ПРИМЕЧАНИЕ : я не могу использовать SOAP с вложением , и я хорошо знаю, что вышеупомянутый подход подвержен сбоям в случае огромных вложений, но на данный момент наш коллега не сдвинется с места.

Ответы [ 4 ]

2 голосов
/ 02 апреля 2009

Вероятно, лучший способ сделать это - прочитать файл и закодировать его содержимое в base64 с помощью кода, который создает XSLT-преобразование . Строка base64 может быть либо передана в качестве параметра для преобразования, либо преобразование может запросить ее через метод расширения.

В принципе XSLT можно использовать для кодирования в base64 , однако некоторые байтовые значения, такие как 0 (для XML 1.0 и XML 1.1) и 29 других кодов ниже 0x20 (для XML 1.0) запрещены как символы в документе XML, и это делает невозможным такое кодирование в XSLT.

(см .: http://projects.ischool.washington.edu/tabrooks/545/ContentManagement/PassingParameters.htm)

1 голос
/ 03 апреля 2009

Если ваш стек SOAP поддерживает MTOM, включите его. То, что тогда будет делать, - это поместить «ссылку» в элементе содержимого на вложение MIME, в которое будут помещены данные. Эти данные могут быть полностью двоичными и не кодироваться в base64.

0 голосов
/ 27 сентября 2010

Вот как я бы отправлял данные по объекту base64Binary (с MTOM или SwAref) в Java, по крайней мере, для целей тестирования (как отмечено в жестко закодированном пути данных).

obj.setContent(
  new DataHandler(
    new URLDataSource(
      this.getClass().getResource("/someDocument.png")
    ));

Хотя обычной операцией будет использование FileDataSource для передачи данных. Хотя я уверен, что у кого-то возникнет идея просто создать свой собственный источник данных. В общем, я думаю, что это было бы плохой идеей, потому что наиболее вероятной реализацией является использование ByteArrayInputStream, который использует память виртуальной машины и может сильно взорваться, если вы отправляете большой файл.

Если вам нужно передать простую строку для тестирования, вы можете сделать следующее:

obj.setContent(
  new DataHandler("test string", "text/plain");

Также, если вы используете среды выполнения WebSphere 7, вам может понадобиться использовать аннотацию @MTOM в реализации службы, если вы заметите, что отправляемые данные содержат только сообщение, но не вложения.

0 голосов
/ 02 апреля 2009

Это не совсем тот ответ, который вы ищете, но процессоры XML, такие как Woodstox текст ссылки , поддерживают эффективное чтение и запись встроенного содержимого в кодировке Base64. В Woodstox 4.0 это делается с использованием так называемого API Typed Access, части API расширения Stax2 (в пакете "org.codehaus.stax2.typed. *", TypedXMLStreamReader, TypedXMLStreamWriter).

Это позволяет потоковое чтение / запись значений элементов и атрибутов, заданных двоичных данных.

Хитрость заключается в том, чтобы соединить это с XSLT. Другой, возможно, более простой способ - выяснить, могут ли клиентские API-интерфейсы (например, CXF или XFire) предоставлять вам доступ к контенту через XMLStreamReader / Writer. Большинство новых основаны на Stax и обычно включают Woodstox.

...