带有Axiom的Spring WS:JAXB正在内联MTOM附件

时间:2012-07-19 16:08:46

标签: java spring jaxb spring-ws mtom

我有web服务来接收和发送附件,我想使用JAXB作为编组程序,但到目前为止,它无法正常工作,因为JAXB将任何作为base64字符串输入或出现在消息正文中的附件,消耗大量内存并经常导致OutOfMemoryError。我正在概述我的设置和修复尝试,并希望有人可以帮助我做到正确。

Axiom是我选择SAAJ作为留言工厂,因为我必须处理大附件。我可以成功地使用JAXB作为参数的编组器并返回端点方法的类型,除非涉及附件(内联问题)。这是我的设置:

Webservices配置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;
    }
}

因此,此代码有效,但与附件无关。我正在寻找一些工作解决方案的时间:

显然最好的帮助来自this other SO question我发布了关于WSS4J发生的这个内联问题。 Blaise Doughan说我需要AttachmentMarshallerAttachmentUnmarshaller设置(联合国)marshaller才能正确处理like he posted in his blog


所以,我假设附件编组是解决这个问题的关键。

要在(联合国)marshaller上设置它们,除了Jaxb2Marshaller并覆盖initJaxbMarshallerinitJaxbUnmarshaller之外,我没有别的办法,设置附件marshallers(我为他们复制了Doughan的代码)在给定(非)marshaller上。

但是我自己的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类已经创建但从未使用过,我不知道为什么,所以我仍然无法测试AttachmentMarshaller是否可以解决问题。

这就是我现在可以说的全部内容。有很多方法可以尝试:

  • 找出为什么MyJaxb2Marshaller被忽略,可能是最简单的;
  • 如果AttachmentMarshaller无法解决问题,
  • 修复JAXB附件内联其他方式,我不知道那会是什么;
  • 将JAXB替换为其他marshaller,同样可行(主要是Axiom支持,可能是WSS4J)。

我在这个问题上已经很长时间了,我一定错过了明显的解决方案。 我们非常欢迎任何帮助。

谢谢!


图书馆版本:

  • Spring 3.1.0(core,beans,oxm等)
  • Spring WS 2.1.0(核心和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(核心)

App服务器是带有Java 1.6.0u14的Oracle 11g R1 Patchset 1。

0 个答案:

没有答案