Search code examples
javaspringspring-bootsoapspring-ws

Support both SOAP 1.1 and SOAP 1.2 messages in Spring-WS


Looked all over for a response to my problem with little success.

I have a Spring boot app which needs to expose both SOAP 1.1 and SOAP 1.2 endpoints. I understand the SOAP version can be configured on the WebServiceMessageFactory bean (currently using SAAJ), but this sets a fixed SOAP version for all endpoints.

Is there a way to achieve this?

Thank you


Solution

  • Doesn't seem to be a built in way of doing this.

    I ended up subclassing SaajSoapMessageFactory and declaring that as a Bean, like this:

    @Bean("messageFactory")
    public SoapMessageFactory messageFactory() {
       var messageFactory = new DualProtocolSaajSoapMessageFactory();
    
       return messageFactory;
    }
    

    This new class is a copy of SaajSoapMessageFactory with a few changes: - It internally has two message factories, one for 1.1 and one for 1.2

    public DualProtocolSaajSoapMessageFactory() {
        super();
    
        try {
            messageFactory11 = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
            messageFactory12 = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
        } catch (Exception ex) {
            throw new SoapMessageCreationException("Could not create SAAJ MessageFactory: " + ex.getMessage(), ex);
        }
    }
    

    And then, basically, just override createWebServiceMessage:

    @Override
    public SaajSoapMessage createWebServiceMessage(InputStream inputStream) throws IOException {
        MimeHeaders mimeHeaders = parseMimeHeaders(inputStream);
        try {
            inputStream = checkForUtf8ByteOrderMark(inputStream);
            SOAPMessage saajMessage = null;
    
            if (mimeHeaders.getHeader(HttpHeaders.CONTENT_TYPE)[0].contains(MimeTypeUtils.TEXT_XML_VALUE)) {
                saajMessage = messageFactory11.createMessage(mimeHeaders, inputStream);
            } else {
                saajMessage = messageFactory12.createMessage(mimeHeaders, inputStream);
            }
    ...snip
    

    A little hacky, but does what it needs to do.