Spring WS z Axiom: JAXB umieszcza załączniki MTOM

Mam usługi sieciowe do odbierania i wysyłania załączników, i chciałbym używać JAXB jako marshallera, ale do tej pory nie działa on prawidłowo, ponieważ JAXB zapisuje wszelkie załączniki przychodzące lub wychodzące w treści wiadomości jako łańcuchy base64, zużywając dużo pamięci i często prowadzi do OutOfMemoryError. Opisuję konfigurację i naprawiam próby i mam nadzieję, że ktoś może mi pomóc.

Axiom jest moim wyborem na SAAJ jako fabrykę wiadomości, ponieważ muszę obsługiwać duże załączniki. Mogę z powodzeniem używać JAXB jako marshallera dla parametrów i typów zwracanych metod końcowych, z wyjątkiem sytuacji, gdy dotyczy to załącznika (problem wbudowany). Oto moja konfiguracja:

XML konfiguracji Webservices:

<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>

Część mojego 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>

Moja klasa punktu końcowego:

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;
    }
}

Zatem ten kod działa, ale nie tak, jak w przypadku załączników. Poszukam pewnego czasu, aby znaleźć rozwiązanie:

Spring Forum: poprawna obsługa MTOM? : sugeruje rozszerzenie niektórych klas aksjomatów, ale kod zmienił się znacznie od tego czasu (2008) i nie mogłem go uruchomić;Spring Forum: Załącznik-odpowiedź / Saaj / Jaxb : możliwą przyczyną jest błąd JVM naprawiony w 1.6u14, który jest używany przez moją wersję Weblogic (plus to nie działa dla twórcy tematu);Wiosenne fora: wysyłanie dużych załączników za pomocą klienta Spring-WS : ktoś rozwiązał problem używając Axis2 bezpośrednio omijając Spring WS, co nie jest celem;Stackoverflow: serwis internetowy Spring-WS z załącznikiem MTOM - Hello world test : ten sam problem co mój, 2 tygodnie, brak odpowiedzi;

Najwyraźniej pochodziła najlepsza pomocto inne pytanie SO Napisałem o tym problemie inliningu z WSS4J. Blaise Doughan powiedział, że potrzebujęAttachmentMarshaller iAttachmentUnmarshaller ustawić na (un) marshallera, aby prawidłowo go obsłużyć,tak jak napisał na swoim blogu.

Zakładam więc, że kluczem do rozwiązania tego problemu są rozdzielacze załączników.

Aby ustawić je na (nie) marszałku, nie widziałem innego wyjścia, jak tylko rozszerzyćJaxb2Marshaller i nadrzędnyinitJaxbMarshaller iinitJaxbUnmarshaller, ustawiając strażników załogi (skopiowałem dla nich kod Doughana) na danym (nie) maszynie.

Ale mój własnyJaxb2Marshaller nie jest używany, nawet podczas ręcznego ustawianiasws: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>

Ta klasa marshallera jest tworzona, ale nigdy nie używana, nie wiem dlaczego, więc nadal nie mogłem sprawdzić, czyAttachmentMarshallers może rozwiązać problem.

To wszystko, co mogę teraz powiedzieć. Istnieje kilka podejść do wypróbowania:

Dowiedz się dlaczegoMyJaxb2Marshaller jest ignorowany, prawdopodobnie najłatwiejszy;napraw załącznik JAXB, wstawiając go w inny sposób, jeśliAttachmentMarshallers nie rozwiąże tego i nie wiem, co by to było;zastąp JAXB innym marshallerem, który działa równie dobrze (głównie wsparcie Axiom, być może WSS4J).

Długo poświęcam temu zagadnieniu i muszę tęsknić za oczywistym rozwiązaniem. Każda pomoc jest mile widziana.

Dzięki!

Wersje biblioteki:

Wiosna 3.1.0 (rdzeń, fasola, oxm itp.)Wiosna WS 2.1.0 (rdzeń i Spring XML)StAX2 2.1WoodSToX 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 (rdzeń)

Serwer aplikacji to Oracle 11g R1 Patchset 1 z Java 1.6.0u14.

questionAnswers(0)

yourAnswerToTheQuestion