Search code examples
javasoapcxfmultipartcxf-client

How to disable cxf SOAP client use multipart request


I have to call a proprietary service that does not support multipart requests, I'm not sending any attachments but cxf seems to create a multipart request

POST /endpoint HTTP/1.1
Content-Type: multipart/related; type="text/xml"; boundary="uuid:86ebef4f-fc2a-431b-a21b-37e86b4901f9"; start="<[email protected]>"; start-info="text/xml"
Accept: */*
Authorization: Basic U1dHMTAwNTA6MTIzNDU1
SOAPAction: "XYZ.0050"
User-Agent: Apache-CXF/3.3.6
Cache-Control: no-cache
Pragma: no-cache
Host: localhost:8082
Connection: keep-alive
Content-Length: 2134


--uuid:86ebef4f-fc2a-431b-a21b-37e86b4901f9
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: binary
Content-ID: <[email protected]>
[etc...]

I've noticed a non-multipart request works fine

POST /endpoint HTTP/1.1
Content-Type: text/xml;charset=UTF-8
Accept: */*
Authorization: Basic U1dHMTAwNTA6MTIzNDU1
Cache-Control: no-cache
Connection: keep-alive
Host: localhost:8082
Pragma: no-cache
SOAPAction: "XYZ.0050"
User-Agent: Apache-CXF/3.3.6
Content-Length: 2114

[etc...]

How do I force cxf to use a non-multipart request?


Solution

  • it looks like cxf creates a multipart any time there is a @XmlAttachmentRef / DataHandler attribute, in my case it is never used so I removed it from my classes.

    a better solution would be to remove the SwAOutInterceptor from the interceptor chain by definining an interceptor remover

    class InterceptorRemover : AbstractSoapInterceptor(Phase.PRE_LOGICAL) {
        init {
            addBefore(SwAOutInterceptor::class.java.name)
        }
        override fun handleMessage(message: SoapMessage?) {
            if (message != null) {
                val res = message.interceptorChain.firstOrNull() { it is SwAOutInterceptor }
                if (res != null) {
                    message.interceptorChain.remove(res)
                }
            }
        }
    }
    

    and add it to the chain:

    val client = ClientProxy.getClient(port)
    client.outInterceptors.add(InterceptorRemover())