Search code examples
javasoapsoap-clientspring-wsmtom

spring ws soap mtom request error - Cannot create message: incorrect content-type for SOAP version. Got multipart/related; but expected text/xml


I am trying to send a mtom enabled soap request which works fine when invoked via SoapUI, but it gives the below error when sent using spring ws api-

SEVERE: SAAJ0533: Cannot create message: incorrect content-type for SOAP version. Got multipart/related; boundary="----=_Part_0_1559020039.1653221075665"; 
    type="application/soap+xml"; start-info="text/xml", but expected text/xml


org.springframework.ws.soap.SoapMessageCreationException: Could not create message from InputStream: Unable to internalize message; nested exception is com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Unable to internalize message

Here is the code for the Soap client:-

FileUploadRequestType fileUploadRequestType = this.objectFactory.createFileUploadRequestType();

        fileUploadRequestType.setFileType(FileTypeType.TXT);
        fileUploadRequestType.setFileName("Transactions_20200424_80.txt");

        fileUploadRequestType.setAttachmentID(new DataHandler(
                Thread.currentThread().getContextClassLoader()
                        .getResource("Transactions_20200424_80.txt")));

        JAXBElement<FileUploadRequestType> fileRequestJAXBElement
                = objectFactory.createFileUploadRequest(fileUploadRequestType);

        WebServiceMessageCallback webServiceMessageCallback = (WebServiceMessage message) -> {

            SoapHeader soapHeader = ((SoapMessage) message).getSoapHeader();
            RequestContextType requestContextType = objectFactory.createRequestContextType();
            requestContextType.setRequestID("c09e319d-8e9f-4a32-9226-0df9f9bf3601");
            requestContextType.setServiceName(SrvcNameType.LYREPORT);
            requestContextType.setRequestChannel(ChannelType.SYSTEM);
            requestContextType.setMessageTime(LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS).toString());
            requestContextType.setPartner(PartnerType.ALPHA);
            JAXBElement<RequestContextType> headerJAXBElement = objectFactory.createRequestContext(requestContextType);

            // create a marshaller
            JAXBContext context = null;
            Marshaller marshaller = null;
            try {
                context = JAXBContext.newInstance(RequestContextType.class);
                marshaller = context.createMarshaller();
                marshaller.marshal(headerJAXBElement, soapHeader.getResult());
            } catch (JAXBException e) {
                System.out.println("Error while marshalling headers.");
                e.printStackTrace();
            }
        };

        ResponseContextType responseContextType = null;
        try {
            getWebServiceTemplate().marshalSendAndReceive(fileRequestJAXBElement, webServiceMessageCallback);
            responseContextType = MtomClientConfig.responseContextType;

        } catch (WebServiceIOException e) {
            System.out.println("Could not connect to the soap web service.");
            throw new RuntimeException(e.getLocalizedMessage());
        } 

Here is the Configuration:-

@Configuration
public class MtomClientConfig {

    public static ResponseContextType responseContextType = new ResponseContextType();

    @Bean
    public Jaxb2Marshaller marshaller() {

        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setContextPath("org.springframework.ws.samples.mtom.client.sws");
        marshaller.setMtomEnabled(true);
        return marshaller;
    }

    @Bean
    public SaajSoapMessageFactory saajSoapMessageFactory() {
        SaajSoapMessageFactory messageFactory = new SaajSoapMessageFactory();
        return messageFactory;
    }


    @Bean
    public SaajMtomClient saajClient(Jaxb2Marshaller marshaller, SaajSoapMessageFactory saajSoapMessageFactory ) throws SOAPException {

        WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
        HttpsUrlConnectionMessageSender messageSender = new HttpsUrlConnectionMessageSender();
        messageSender.setTrustManagers(new TrustManager[]{new UnTrustworthyTrustManager()});

        webServiceTemplate.setMessageSender(messageSender);
        webServiceTemplate.setMessageFactory(saajSoapMessageFactory);
        
        SaajMtomClient client = new SaajMtomClient();
        client.setWebServiceTemplate(webServiceTemplate);
        client.setDefaultUri("https://host:port/GW/AlphaServices/FileUpload");
        client.setMarshaller(marshaller);
        client.setUnmarshaller(marshaller);
        return client;
    }
}

I also tried setting the SOAP version 1.2 by configuring the below MessageFactories but then it gives the below error:-

SEVERE: SAAJ0415: InputStream does not represent a valid SOAP 1.2 Message

org.springframework.ws.soap.SoapMessageCreationException: Could not create message from InputStream: InputStream does not represent a valid SOAP 1.2 Message; nested exception is javax.xml.soap.SOAPException: InputStream does not represent a valid SOAP 1.2 Message

MessageFactory to set SOAP version 1.2:-

    @Bean
    public SaajSoapMessageFactory saajSoapMessageFactory() {
        SaajSoapMessageFactory messageFactory = new SaajSoapMessageFactory();
        messageFactory.setSoapVersion(SoapVersion.SOAP_12);
        return messageFactory;
    }

//    @Bean
//    public WebServiceMessageFactory webServiceMessageFactory() throws SOAPException {
//        SaajSoapMessageFactory saajSoapMessageFactory = new SaajSoapMessageFactory();
//        saajSoapMessageFactory.setSoapVersion(SoapVersion.SOAP_12);
//        return saajSoapMessageFactory;
//    }

Also another point I think I should add to the problem is that, when I tried sending the request without the headers section(commented the code inside WebServiceMessageCallback), it actually worked but obviously received a bad response from the webservice, but the point here is that it actually worked without headers may be that's where we need to look.

Please let me know if I should add more info to the question.


Solution

  • Okay, finally after long debugging, the integration works. But I did not change a single letter in my code. It seems the service provider changed something at their end, to which they did not confirm upon enquiring. I know its like what?? are you serious?? I was just trying to debug a code which was completely fine all this time?? common...I know its disappointing..Just wanted to post the answer so that someone who's facing a similar issue an already debugged all possible aspects should check the very basic - 1) if they are using the updated and correct wsdl file 2) make sure the service provider/consumer has the right set of configuration in place.