Description
Mauro Molinari opened SWS-905 and commented
I had a very poor experience trying to enable MTOM attachment handling on a receiving endpoint expecting JAXB input parameters. Please let me write the whole story.
I have to receive web service requests as defined by the following contract: http://www.fatturapa.gov.it/export/fatturazione/sdi/ws/trasmissione/v1.0/TrasmissioneFatture_v1.1.wsdl
and the imported schema: http://www.fatturapa.gov.it/export/fatturazione/sdi/ws/trasmissione/v1.0/TrasmissioneTypes_v1.1.xsd
With the following configuration I could make it almost work:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:web-services="http://www.springframework.org/schema/web-services"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"
default-lazy-init="true">
<context:component-scan base-package="mypackage" />
<web-services:annotation-driven />
<web-services:static-wsdl id="TrasmissioneFatture"
location="classpath:/wsdl/TrasmissioneFatture_v1.1.wsdl" />
<bean id="TrasmissioneTypes_v1.1" class="org.springframework.xml.xsd.SimpleXsdSchema">
<property name="xsd" value="classpath:/wsdl/TrasmissioneTypes_v1.1.xsd" />
</bean>
</beans>
@Endpoint
public class TrasmissioneFattureEndpoint {
@SoapAction("http://www.fatturapa.it/TrasmissioneFatture/RicevutaConsegna")
public void ricevutaConsegna(@RequestPayload FileSdIType input) {
// processing
}
where FileSdiType
is a Java class generated by running the JAXB compiler XJC against the above XSD file. Please note that FileSdiType
is annotated with @XmlType
and not with @XmlRootElement
(actually, no generated class has the @XmlRootElement
annotation...).
Contrary to what the reference documentation says, unmarshalling for FileSdType
works even if it is not annotated with @XmlRootElement
, but that's fine for me: the code and configuration are very brief and neat!
This almost worked perfectly. I say "almost" because one of the elements of FileSdType
schema type is a binary attachment. By trying to retrieve its content in the endpoing implementation using the InputStream
on the DataHandler
exposed by the corresponding Java type, all works fine as long as the client sends the attachment as an inline base64 binary string.
But if the client uses MTOM, the input stream reads nothing.
The first reaction was: well, I would have expected it to work out of the box, since MTOM is said to be the de-facto standard for attachments.
The second thought was: let's look at the reference documentation better... but nothing relevant is said for this use case.
The third was: let's search with Google.
The actual solution was given by this StackOverflow answer: http://stackoverflow.com/questions/11316023/spring-ws-webservice-with-mtom-attachement-hello-world-test/11576245#11576245
That is: define a Jaxb2Marshaller
with enabled MTOM, define a MarshallingPayloadMethodProcessor
that uses it, define a DefaultMethodEndpointAdapter
that uses that processor, define a message receiver of type SoapMessageDispatcher
that uses that method endpoint adapter and make the MessageDispatcherServlet
use that message receiver.
With all of this lengthy configuration, I could make it work, but:
- there's a lot of (manual) configuration to set up and there's no indication in the reference guide on how to do this
- after founding the StackOverflow question, I discovered there's a MTOM example project in the spring-ws-samples GitHub project, but:
- I couldn't find any link to this project in the Spring Web Services website on spring.io (I found it by chance using Google...)
- I couldn't find any mention to that samples project in the reference guide
- the sample uses Java configuration (not XML), so a bit of translation is required in my case; nevertheless, I couldn't find where the message receiver is configured, which is an essential part of the configuration (I debugged my configuration and, without it, the default method endpoint adapter created by the Spring WS namespace tags is still preferred and used, so MTOM attachment handling doesn't work)
- while
org.springframework.ws.server.endpoint.adapter.method.jaxb.XmlRootElementPayloadMethodProcessor.supportsRequestPayloadParameter(MethodParameter)
checks for both the presence of@XmlRootElement
and@XmlType
,org.springframework.oxm.jaxb.Jaxb2Marshaller.supportsInternal(Class<?>, boolean)
only checks for the former annotation and not for the latter, so I had to change my endpoint method signature to useJaxbElement<FileSdIType>
(which IMHO introduces useless noise in the endpoint implementation) - another (smaller) annoyance is that if I define my
Jaxb2Marshaller
I have to explicitly set its context path (or packages/classes to scan/support), while with the default non-MTOM enabled configuration this is not required, because the appropriate Jaxb2 marshaller is found automatically (I think it's thanks toorg.springframework.ws.server.endpoint.adapter.method.jaxb.AbstractJaxb2PayloadMethodProcessor.createUnmarshaller(Class<?>)
andorg.springframework.ws.server.endpoint.adapter.method.jaxb.AbstractJaxb2PayloadMethodProcessor.getJaxbContext(Class<?>)
)
I think all of this should be improved, or at least documented. Also, if the requirement to explicitely enable MTOM on the marshaller is desirable, why this shouldn't just work?
<web-services:annotation-driven marshaller="marshaller" unmarshaller="marshaller" />
where marshaller
is my MTOM-enabled Jaxb2Marshaller
? In my tests, this does not work (i.e.: specifying the marshaller in the <web-services:annotation-driven>
tag is unexpectedly totally useless for this use case).
Probably this is related to #793, which was closed as deferred probably because of a lack of resources, However, in the short-mid term, if this could not be improved, at least please document it in the reference guide: I don't think the need for a MTOM+JAXB working solution is so uncommon.
Affects: 2.2.1
Issue Links:
- Improve the experience to enable MTOM with JAXB [SWS-904] #981 Improve the experience to enable MTOM with JAXB
("supersedes")
Referenced from: commits 1520740
1 votes, 3 watchers