Issue
There is this legacy system which is sending SOAP requests with an empty namespace attribute causing fields values to be null, when namespace attribute is removed while testing from SOAP UI, it work fine.
This is what problematic SOAP request looks like
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ADD xmlns="http://www.cc.com/ws">
<ID xmlns="">dummy</ID>
<PWD xmlns="">password</PWD>
</ADD>
</soapenv:Body>
</soapenv:Envelope>
I tried by adding an interceptor using addInterceptors
method of WsConfigurerAdapter
, code of which is pasted below, but it doesn't work
@Override
public boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception {
SOAPMessage soapMessage = ((SaajSoapMessage) messageContext.getRequest()).getSaajMessage();
SOAPBody body = soapMessage.getSOAPBody();
Iterator<SOAPBodyElement> it = body.getChildElements();
while (it.hasNext()) {
Object node = it.next();
if (!isTextNode(node)) {
com.sun.xml.internal.messaging.saaj.soap.ver1_1.BodyElement1_1Impl e =
(com.sun.xml.internal.messaging.saaj.soap.ver1_1.BodyElement1_1Impl) node;
Iterator<SOAPBodyElement> subItr = e.getChildElements();
while(subItr.hasNext()) {
Object subNode = subItr.next();
if(subNode instanceof com.sun.xml.internal.messaging.saaj.soap.impl.ElementImpl) {
SOAPElement el = (SOAPElement) subNode;
el.removeAttribute("xmlns");
}
}
}
}
soapMessage.writeTo(System.out);
return true;
}
Solution
Note that a namespace declaration in XML is not an attribute. Don't be confused by the similar syntax!
So I would not expect e.removeAttribute
to do anything, because there is no attribute with the name xmlns
.
What you actually need to do is to change the name of the element, e.g. using its setElementQName() method.
@Override
public boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception {
SOAPMessage soapMessage = ((SaajSoapMessage) messageContext.getRequest()).getSaajMessage();
SOAPBody body = soapMessage.getSOAPBody();
Iterator<SOAPBodyElement> it = body.getChildElements();
while (it.hasNext()) {
Object node = it.next();
if (!isTextNode(node)) {
com.sun.xml.internal.messaging.saaj.soap.ver1_1.BodyElement1_1Impl e =
(com.sun.xml.internal.messaging.saaj.soap.ver1_1.BodyElement1_1Impl) node;
Iterator<SOAPBodyElement> subItr = e.getChildElements();
while(subItr.hasNext()) {
Object subNode = subItr.next();
if(subNode instanceof com.sun.xml.internal.messaging.saaj.soap.impl.ElementImpl) {
SOAPElement el = (SOAPElement) subNode;
el.setElementQName(
new QName(
e.getElementName().getURI(),
el.getElementName().getLocalName()
)
);
}
}
}
}
soapMessage.writeTo(System.out);
return true;
}
Answered By - Conal Tuohy
Answer Checked By - Cary Denson (JavaFixing Admin)