CodeScale
CodeScale

Reputation: 3304

Spring ws - Datahandler with Swaref still null

I use the Spring boot starter web services to develop a SOAP with attachment service.

For an unknown reason attachments aren't unmarshalled.. Jaxb Unmarshaller is used but the property AttachmentUnmarshaller inside is "null" ...so probably the reason why DataHandler unmarshalling isn't done ??

As in a JEE environment the attachmentUnmarshaller is handle by jaxws .. how configure it in a standalone process like spring boot on tomcat ??

Java version : 8_0_191

Spring boot version : 2.1

Upvotes: 2

Views: 1631

Answers (1)

user3589891
user3589891

Reputation: 41

I faced similar issue, but with marshalling.

Jaxb2Marshaller has its own implementations of AttachmentMarshaller and AttachmentUnarshaller. But for these to work, mtomEnabled property should be set to true. If it's not, defaults will be used, which are not instantiated.

Try setting setMtomEnabled(true) on your Jaxb2Marshaller. This will probably solve your issue.

For people, who encounter same issue with marshalling - it's a bit more complicated. Jaxb2 AttachmentMarshaller is not correctly implemented as per WS-I Attachment Profile 1.0 - http://www.ws-i.org/Profiles/AttachmentsProfile-1.0.html#Example_Attachment_Description_Using_swaRef

You will have to override marshalling behavior of Jaxb2Marshaller then.

Notice: this solution assumes that MTOM is always disabled.

@Configuration
class SOAPConfiguration {
    @Bean
    public Jaxb2Marshaller jaxb2Marshaller() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller() {
            @Override
            public void marshal(Object graph, Result result, @Nullable MimeContainer mimeContainer) throws XmlMappingException {
                try {
                    javax.xml.bind.Marshaller marshaller = createMarshaller();
                    if (mimeContainer != null) {
                        marshaller.setAttachmentMarshaller(
                                new SwaRefAttachmentMarshaller(mimeContainer)
                        );
                        marshaller.marshal(graph, result);
                    } else {
                        super.marshal(graph, result, null);
                    }
                } catch (JAXBException ex) {
                    throw convertJaxbException(ex);
                }
            }
        };
        marshaller.setPackagesToScan("my.package");

        marshaller.setMtomEnabled(false);

        return marshaller;
    }

    private class SwaRefAttachmentMarshaller extends AttachmentMarshaller {

        private final MimeContainer mimeContainer;

        private SwaRefAttachmentMarshaller(MimeContainer mimeContainer) {
            this.mimeContainer = mimeContainer;
        }

        @Override
        public String addMtomAttachment(DataHandler data, String elementNamespace, String elementLocalName) {
            return null;
        }

        @Override
        public String addMtomAttachment(byte[] data, int offset, int length, String mimeType, String elementNamespace, String elementLocalName) {
            return null;
        }

        @Override
        public String addSwaRefAttachment(DataHandler data) {
            String attachmentId = UUID.randomUUID().toString();
            mimeContainer.addAttachment("<" + attachmentId + ">", data);

            return "cid:" + attachmentId;
        }
    }
}

Upvotes: 4

Related Questions