Java SpringWS和Axiom:JAXB正在内联MTOM附件

Java SpringWS和Axiom:JAXB正在内联MTOM附件,java,spring,jaxb,spring-ws,mtom,Java,Spring,Jaxb,Spring Ws,Mtom,我有Web服务来接收和发送附件,我想使用JAXB作为封送器,但到目前为止它还不能正常工作,因为JAXB将消息体中传入或传出的任何附件作为base64字符串内联,这会消耗大量内存,并经常导致OutOfMemoryError。我概述了我的设置和修复尝试,希望有人能帮我把它做好 Axiom是我的选择,而不是SAAJ作为消息工厂,因为我必须处理大型附件。我可以成功地使用JAXB作为端点方法的参数和返回类型的封送器,除非涉及附件(内联问题)。这是我的设置: Web服务配置XML: <beans xm

我有Web服务来接收和发送附件,我想使用JAXB作为封送器,但到目前为止它还不能正常工作,因为JAXB将消息体中传入或传出的任何附件作为base64字符串内联,这会消耗大量内存,并经常导致OutOfMemoryError。我概述了我的设置和修复尝试,希望有人能帮我把它做好

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

Web服务配置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>
因此,这段代码可以工作,但与附件不同。我正在搜索一段时间的workign解决方案:

  • :建议扩展一些Axiom类,但自(2008年)以来,代码发生了很大变化,我无法让它工作
  • :可能原因是1.6u14中修复的JVM错误,这是我的Weblogic版本使用的错误(加上主题创建者无法使用)
  • :有人使用Axis2直接绕过Spring WS解决了问题,这不是重点
  • :与我的问题相同,2周大,没有答案
显然,最好的帮助来自我发布的关于WSS4J内联问题的帖子。Blaise Doughan说我需要在(un)marshaller上设置
AttachmentMarshaller
AttachmentUnmarshaller
以正确处理它


所以,我假设附件封送器是解决这个问题的关键

要在(un)封送拆收器上设置它们,除了扩展
Jaxb2Marshaller
和overide
initJaxbMarshaller
initJaxbUnmarshaller
,在给定(un)封送拆收器上设置附件封送拆收器(我为它们复制了Doughan的代码)

但是我自己的
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>

com.example.webservice.oxm.FileTestResponse
com.example.webservice.oxm.FileTestRequest
这个marshaller类是创建的,但从未使用过,我不知道为什么,所以我仍然无法测试
AttachmentMarshaller
s是否可以解决这个问题

现在我只能说这些了。有很多方法可以尝试:

  • 找出
    MyJaxb2Marshaller
    被忽略的原因,这可能是最简单的
  • 如果
    AttachmentMarshaller
    s无法解决JAXB附件的内联问题,我不知道会是什么
  • 用其他同样有效的marshaller替换JAXB(主要是Axiom支持,可能是WSS4J)
我在这个问题上花了很长时间,我一定错过了显而易见的解决办法。 欢迎任何帮助

谢谢


图书馆版本:

  • Spring 3.1.0(核心、bean、oxm等)
  • SpringWS2.1.0(核心和SpringXML)
  • StAX2 2.1
  • WoodSToX 3.2.9(wstx)
  • JAXB 2.2.5-2(API+impl)
  • Apache Axiom 1.2.13(API+impl+c14n+dom)
  • ApacheMe4J 0.7.2(核心)

App server是带有Java 1.6.0u14的Oracle 11g R1修补程序集1。

以下内容是否有帮助@BlaiseDoughan我尝试了那段代码,我可以成功地添加附件,但是我不能让
数据
字段用XOP引用它,它一如既往地内联数据,尽管附加了相同的数据。Spring论坛上的旧消息(2007年至2010年)说,MTOM支持只对SAAJ可用,这是您刚才发布的答案中使用的。
AxiomSoapMessage.convertoxoppackage
的代码仍然是空的,因此从那以后它似乎一直没有被触动过。我不知道我如何才能在Spring上修补Axiom以使附件响应工作。。。在JavaEEJAX-WS实现中,JAX-WS实现将直接与JAXB交互,并设置附件处理程序本身,然后一切自动工作。我正在尝试拼凑Spring WS的功能。很抱歉,我之前没有回复。我最终还是成功了。请参阅我的另一个线程()上的更新。如果您仍在努力,请告诉我,我将通过电子邮件向您发送一个工作副本示例。@ziggy感谢您的解决方案。这是可行的,但只适用于SAAJ。我将继续寻找一个Axiom=)
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;
    }
}
<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>