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.

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 use JaxbElement<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 to org.springframework.ws.server.endpoint.adapter.method.jaxb.AbstractJaxb2PayloadMethodProcessor.createUnmarshaller(Class<?>) and org.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?

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 SWS-825, 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.

Activity

Another info that may be useful to know. I tried to extend the Spring WS classes to support the unwrapping of XmlType annotated types in endpoint methods with the above configuration that supports MTOM, to get rid of the requirement to have methods with JAXBElement arguments.
In addition to extending org.springframework.oxm.jaxb.Jaxb2Marshaller to add the XmlType annotated case in supportsInternal(Class, boolean (which is made harder by the fact that this method is private), there's an issue in org.springframework.ws.server.endpoint.adapter.method.MarshallingPayloadMethodProcessor.resolveArgument(MessageContext, MethodParameter), which simply ignores the parameter argument and delegates the resolution to the marshaller. This can't know which kind of parameters should be returned and therefore always returns a JAXBElement result (in the Jaxb2Marshaller case). So, it could be a MarshallingPayloadMethodProcessor responsibility to unwrap the JAXBElement in case the MethodParameter is not referring to a JAXBElement parameter. However this introduces a dependency between the MarshallingPayloadMethodProcessor and a specific type of marshaller, which is bad.

In the non-MTOM enabled default configuration, this is resolved by registering two method processors (a JaxbElementPayloadMethodProcessor and a XmlRootElementPayloadMethodProcessor) which take care of the different cases, however this would require me to register two method MarshallingPayloadMethodProcessor}}s with two different JAXB2 marshaller implementations, one that does the unwrapping when unmarshalling and one that does not. Probably a bit better, but even more complex, because the {{Jaxb2Marshaller should be configurable to do this...

Mauro Molinari
added a comment - 08/Jul/15 9:36 AM Another info that may be useful to know. I tried to extend the Spring WS classes to support the unwrapping of XmlType annotated types in endpoint methods with the above configuration that supports MTOM, to get rid of the requirement to have methods with JAXBElement arguments.
In addition to extending org.springframework.oxm.jaxb.Jaxb2Marshaller to add the XmlType annotated case in supportsInternal(Class, boolean (which is made harder by the fact that this method is private), there's an issue in org.springframework.ws.server.endpoint.adapter.method.MarshallingPayloadMethodProcessor.resolveArgument(MessageContext, MethodParameter) , which simply ignores the parameter argument and delegates the resolution to the marshaller. This can't know which kind of parameters should be returned and therefore always returns a JAXBElement result (in the Jaxb2Marshaller case). So, it could be a MarshallingPayloadMethodProcessor responsibility to unwrap the JAXBElement in case the MethodParameter is not referring to a JAXBElement parameter. However this introduces a dependency between the MarshallingPayloadMethodProcessor and a specific type of marshaller, which is bad.
In the non-MTOM enabled default configuration, this is resolved by registering two method processors (a JaxbElementPayloadMethodProcessor and a XmlRootElementPayloadMethodProcessor ) which take care of the different cases, however this would require me to register two method MarshallingPayloadMethodProcessor}}s with two different JAXB2 marshaller implementations, one that does the unwrapping when unmarshalling and one that does not. Probably a bit better, but even more complex, because the {{Jaxb2Marshaller should be configurable to do this...