Search code examples
jaxbunmarshallingmtomapache-tomee

JAXB Unmarshalling with MTOM


I have a problem unmarshalling MTOM for a RetrieveDocumentSetResponse, which is part of XDS.

In my generated JAXB files, I simply have an element document which is a byte[]. After I perform the usual unmarshalling steps:

final JAXBContext jc = JAXBContext.newInstance(RetrieveDocumentSetResponseType.class);
final Unmarshaller u = jc.createUnmarshaller();

final JAXBElement<RetrieveDocumentSetResponseType> rdsJaxb = u.unmarshal(
                    soapResponse.getSOAPBody().getElementsByTagNameNS("urn:ihe:iti:xds-b:2007", "RetrieveDocumentSetResponse").item(0),
                    RetrieveDocumentSetResponseType.class);
final RetrieveDocumentSetResponseType rdsResp = rdsJaxb.getValue();

My document is empty: rdsResp.getDocument().length == 0.

In checking with TCPMonitor I see that the document is getting sent over the line, so the error must be somewhere in the unmarshalling.

I have tried using a DataHandler instead of a byte[] and annotating the document variable with an @XMLMimeType annotation to no avail. I'm using TomEE as my deployment target which uses the RI version of JAXB I believe.

I'm also using regular dispatching for the web service call, making sure to enable MTOM:

final Service repoService;
final QName repoPort = new QName(XdsProperties.XDS_REPOSITORY_NAMESPACE, XdsProperties.XDS_REPOSITORY_PORT);
        if (XdsProperties.XDS_REPOSITORY_WSDL == null) {
            repoService = Service.create(new QName(XdsProperties.XDS_REPOSITORY_NAMESPACE, XdsProperties.XDS_REPOSITORY_SERVICE));
        } else {
            repoService = Service.create(XdsProperties.XDS_REPOSITORY_WSDL, new QName(XdsProperties.XDS_REPOSITORY_NAMESPACE,
                    XdsProperties.XDS_REPOSITORY_SERVICE));
        }
        repoService.addPort(repoPort, SOAPBinding.SOAP12HTTP_MTOM_BINDING, XdsProperties.XDS_REPOSITORY_ENDPOINT);
final MTOMFeature mtomFt = new MTOMFeature(true);
REPOSITORY_DISPATCH = repoService.createDispatch(repoPort, SOAPMessage.class, Service.Mode.MESSAGE, addrFt, mtomFt);

And I even do:

REPOSITORY_DISPATCH.getRequestContext().put(BindingProvider.SOAPACTION_URI_PROPERTY, soapAction);       
final SOAPBinding binding = (SOAPBinding) REPOSITORY_DISPATCH.getBinding();         
binding.setMTOMEnabled(true);

I'm really not sure what's going wrong or what I'm supposed to do since no exceptions are being thrown, the document is just always empty.


Solution

  • In order for attachments to be resolved during a JAXB unmarshal an AttachmentUnmarshaller needs to be set on the Unmarshaller.

    When JAXB is leveraged under the covers by JAX-WS this is handled automatically. If you are interacting with the XML directly you will need to implement and set the AttachmentUnmarshaller your self. Below is a link to an example that will help: