Spring WS с Axiom: JAXB включает вложения MTOM
У меня есть веб-сервисы для приема и отправки вложений, и я хотел бы использовать JAXB в качестве маршаллера, но пока он не работает должным образом, поскольку JAXB вставляет любое вложение, входящее или выходящее в теле сообщения, в виде строк base64, потребляя много памяти и часто приводит к OutOfMemoryError. Я обрисовываю в общих чертах мои попытки установки и исправления и надеюсь, что кто-то может помочь мне сделать это правильно.
Аксиома - это мой выбор, а не 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: correct MTOM handling? : suggests extending some Axiom classes, but the code changed considerably ever since (2008), and I couldn't get it working; Spring Forums: Response-Attachment/Saaj/Jaxb : possible cause by a JVM bug fixed in 1.6u14, which is the one used by my Weblogic version (plus it didn't work for the topic creator); Spring Forums: sending large attachments with Spring-WS client : someone solved using Axis2 directly bypassing Spring WS, which is not the point; Stackoverflow: Spring-WS webservice with MTOM attachement - Hello world test : same issue as mine, 2 weeks old, no answers;По-видимому, лучшая помощь пришла отэтот другой ТАК вопрос Я написал об этой встраиваемой проблеме, происходящей с 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>
Этот класс маршаллера создан, но никогда не используется, я не знаю почему, поэтому я все еще не могу проверить,AttachmentMarshaller
s может решить проблему.
Это все, что я могу сказать сейчас. Есть довольно много подходов, чтобы попробовать:
find out whyMyJaxb2Marshaller
is being ignored, probably the easiest;
fix JAXB attachment inlining some other way if AttachmentMarshaller
s won't solve it, and I don't know what that would be;
replace JAXB with other marshaller, that works just as well (mainly Axiom support, possibly WSS4J).
Я давно нахожусь в этом вопросе, и я, должно быть, упускаю очевидное решение. Любая помощь приветствуется.
Спасибо!
Версии библиотеки:
Spring 3.1.0 (core, beans, oxm and such) Spring WS 2.1.0 (core and Spring XML) StAX2 2.1 WoodSToX 3.2.9 (wstx) JAXB 2.2.5-2 (API+impl) Apache Axiom 1.2.13 (API+impl+c14n+dom) Apache Mime4j 0.7.2 (core)Сервер приложений - Oracle 11g R1 Patchset 1 с Java 1.6.0u14.