У меня есть веб-сервисы для получения и отправки вложений, и я хотел бы использовать JAXB в качестве маршаллера, но пока он работает неправильно, поскольку JAXB встраивает любое входящее или исходящее вложение в тело сообщения в виде строк base64, потребляя много памяти и часто приводит к OutOfMemoryError. Я описываю свои попытки установки и исправления и надеюсь, что кто-то поможет мне сделать это правильно.
В качестве фабрики сообщений я выбрал Axiom, а не SAAJ, так как мне приходится обрабатывать большие вложения. Я могу успешно использовать JAXB в качестве маршаллера для параметров и возвращаемых типов методов конечной точки, за исключением случаев, когда задействовано вложение (встроенная проблема). Это моя установка для него:
XML конфигурации веб-сервисов:
<beans xmlns=...>
<context:component-scan base-package="com.example.webservice" />
<sws:annotation-driven />
<bean id="jaxb2Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>com.example.webservice.oxm.FileTestResponse</value>
<value>com.example.webservice.oxm.FileTestRequest</value>
</list>
</property>
<property name="mtomEnabled" value="true"/>
</bean>
<bean id="messageFactory" class="org.springframework.ws.soap.axiom.AxiomSoapMessageFactory">
<property name="payloadCaching" value="true"/>
<property name="attachmentCaching" value="true"/>
</bean>
<sws:dynamic-wsdl id="fileTest" portTypeName="fileTest" locationUri="/webservice/fileTest/" targetNamespace="http://example.com/webservice/definitions" >
<sws:xsd location="/WEB-INF/fileTest.xsd" />
</sws:dynamic-wsdl>
</beans>
Часть моего XSD:
<!-- I generate the marshalling classes with XJB, and using
xmime:expectedContentTypes it correctly creates mtomData field
with DataHandler type instead of byte[] -->
<xs:element name="fileTestRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="mtomData" type="xs:base64Binary"
xmime:expectedContentTypes="application/octet-stream"/>
</xs:sequence>
</xs:complexType>
</xs:element>
Мой класс конечной точки:
package com.example.webservice;
import ...
@Endpoint
@Namespace(prefix = "s", uri = FileTestEndpoint.NAMESPACE)
public class FileTestEndpoint {
public static final String NAMESPACE = "http://example.com/webservice/schemas";
@PayloadRoot(localPart = "fileTestRequest", namespace = NAMESPACE)
@ResponsePayload
public FileTestResponse fileTest(@RequestPayload FileTestRequest req) throws IOException {
// req.getMtomData() and do something with it
FileTestResponse resp = new FileTestResponse();
DataHandler dataHandler = new DataHandler(new ByteArrayDataSource("my file download data".getBytes(), "text/plain"));
resp.setData(dataHandler);
return resp;
}
}
Итак, этот код работает, но не так, как с вложениями. Я ищу какое-то время для рабочего решения:
- Spring Forums: правильная обработка MTOM?: предлагает расширить некоторые Axiom классы, но с 2008 года код значительно изменился, и я не мог заставить его работать;
- Форумы Spring: Response-Attachment/Saaj/Jaxb : возможная причина - ошибка JVM, исправленная в 1.6u14, которая используется в моей версии Weblogic (плюс это не сработало для создателя темы);
- Форумы Spring: отправка больших вложений с помощью Spring -WS-клиент: кто-то решил использовать Axis2 напрямую, минуя Spring WS, что не имеет значения;
- Stackoverflow: веб-служба Spring-WS с вложением MTOM - Hello world test : та же проблема, что и у меня, 2 недели назад, ответов нет;
По-видимому, лучшая помощь пришла из этот другой вопрос SO, который я опубликовал об этой проблеме встраивания происходит с WSS4J. Блейз Доуган сказал, что мне нужно установить AttachmentMarshaller и AttachmentUnmarshaller на (не)маршаллере, чтобы он правильно обрабатывался, как он написал в своем блоге.
Итак, я предполагаю, что упорядочители вложений являются ключом к решению этой проблемы.
Чтобы установить их на (не)маршаллере, я не видел другого пути, кроме как расширить Jaxb2Marshaller и переопределить initJaxbMarshaller и initJaxbUnmarshaller, установив маршалеры вложений (я скопировал для них код Дугана) на заданный (не)маршаллер.
Но мой собственный Jaxb2Marshaller не используется, даже если вручную установить sws:annotation-driven:
<sws:annotation-driven marshaller="jaxb2Marshaller" unmarshaller="jaxb2Marshaller"/>
<bean id="jaxb2Marshaller" class="com.example.webservice.MyJaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>com.example.webservice.oxm.FileTestResponse</value>
<value>com.example.webservice.oxm.FileTestRequest</value>
</list>
</property>
<property name="mtomEnabled" value="true"/>
</bean>
Этот класс Marshaller создан, но никогда не используется, я не знаю почему, поэтому я все еще не мог проверить, может ли AttachmentMarshallers решить проблему.
Это все, что я могу сказать на данный момент. Есть довольно много подходов, которые можно попробовать:
- выяснить, почему
MyJaxb2Marshallerигнорируют, наверное, проще всего; - исправить встраивание вложения JAXB каким-либо другим способом, если
AttachmentMarshallers не решит эту проблему, и я не знаю, что это может быть; - замените JAXB на другой маршаллер, который работает так же хорошо (в основном поддержка Axiom, возможно, WSS4J).
Я долго занимаюсь этим вопросом, и мне, должно быть, не хватает очевидного решения. Любая помощь приветствуется.
Спасибо!
Версии библиотеки:
- Spring 3.1.0 (ядро, beans, oxm и т. д.)
- Spring WS 2.1.0 (ядро и Spring XML)
- StAX2 2.1
- WoodSToX 3.2.9 (wstx)
- JAXB 2.2.5-2 (API+внедрение)
- Apache Axiom 1.2.13 (API+импл+c14n+дом)
- Apache Mime4j 0.7.2 (ядро)
Сервер приложений — Oracle 11g R1 Patchset 1 с Java 1.6.0u14.
dataссылаться на него с помощью XOP, оно как всегда встраивает данные, несмотря на то, что те же данные прикреплены. В старых сообщениях (с 2007 по 2010 год) на форумах Spring говорится, что поддержка MTOM была доступна только для SAAJ, что и использовалось в ответе, который вы только что опубликовали. Код дляAxiomSoapMessage.convertToXopPackageвсе еще пуст, так что с тех пор он кажется нетронутым. Я не уверен, как мне нужно исправить Axiom на Spring, чтобы заставить работать ответ на вложение... возможно, это также понадобится для запросов на вложение. - person mdrg   schedule 19.07.2012