I'm working on a webservice that uses SOAP as a communication protocol: I achieve this by using Spring Boot and Spring WS.
Sometimes, it may happen that I need to send some stuff through the request's header and I want to be able to recover that information via an XPath expression.
Here's what I did so far:
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
WebServiceMessage message = messageContext.getRequest();
Source s = messageContext.getRequest().getPayloadSource();
messageContext.getRequest().writeTo(buffer);
String payload = buffer.toString(java.nio.charset.StandardCharsets.UTF_8.name());
System.out.println(payload);
InputStream is = new ByteArrayInputStream(payload.getBytes());
In the following code snippet I read the whole request that get back-end receives. Afterwards, what I used to do was to transform all of this in a SOAPHeader object, that held everything that I wanted.... except for the fact that I couldn't make any XPath query at all and the element I needed where really down the tree.
So, I decided to continue that snippet of code in the following way
//-------
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new java.io.ByteArrayInputStream(payload.getBytes()));
XPath xpath = XPathFactory.newInstance().newXPath();
Now, this is a sample of the request I'm sending over
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:it="it.niuma.mscsoapws.ws">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-3967AEB46D733EF6E2154990461080350">
<wsse:Username>TAVI</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">pUn8VjdpVaIamSAIwXEeXg==</wsse:Nonce>
<wsu:Created>2019-02-11T17:03:30.803Z</wsu:Created>
</wsse:UsernameToken></wsse:Security>
</soapenv:Header>
<soapenv:Body>
<it:getPOrderRequest>
<it:poNumber>2197111225-F03292</it:poNumber>
</it:getPOrderRequest>
</soapenv:Body>
</soapenv:Envelope>
What I want to extrapolate is the entire part inside soapenv:Header, so I use the following XPath Expression:
XPathExpression expr = xpath.compile("//*//soapenv:Header");
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
for (int i = 0; i < nodes.getLength(); i++) {
Node currentItem = nodes.item(i);
System.out.println("found node -> " + currentItem.getLocalName() + " (namespace: " + currentItem.getNamespaceURI() + ")");
}
Here's my problem: the XPath expression, Java side, doesn't return anything while other tools (like this one) evaluates the expression correctly and return something. The only XPath expression that gets correctly evaluated in Java is //*, nothing else. What am I missing?
EDIT: After @Wisthler's suggestion, the XPath is now evaluated but it fails to return something. Attaching a screenshot of what happens now: see how the nodes variable (which should contain a NodesList) is, if I understood correctly, empty