1

I want to show the response that the server sends me, but at the time of parsing it shows me the empty string. I've tried parsing the server response as shown in other tutorials, but it does not work. Does anyone know I'm doing wrong?

JAVA CODE

import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.w3c.dom.Document;
import freemarker.template.Configuration;
import freemarker.template.Template;
public class ClienteSoap {
    public static void main(String[] args) {
        HttpClient httpClient = null;   

          try {
            Configuration cfg = new Configuration();

            // Cargar plantilla
            Template template = cfg.getTemplate("src/main/resources/templates/template.ftl");

            // Modelo de datos
            Map<String, Object> data = new HashMap<String, Object>();
            data.put("token", "u757Ric6542ytu6Ricgtr0");
            data.put("branch", "1");
            data.put("app", "S-04600");
            data.put("folio", "4345Ric67");
            data.put("temp", "False");


            // Crear mensaje SOAP HTTP
            StringWriter out = new StringWriter();
            template.process(data, out);
            String strRequest = out.getBuffer().toString();
            System.out.println(strRequest);

            // Crear la llamada al servidor
            httpClient = new DefaultHttpClient();
            HttpPost postRequest = new
            HttpPost("http://127.0.0.1:30005/PCIServicioConciliadorCore-web"); //direccion de la pagina
            StringEntity input = new StringEntity(strRequest);
            input.setContentType("text/xml");
            postRequest.setEntity(input);

            // Tratar respuesta del servidor
            HttpResponse response = httpClient.execute(postRequest);
            if (response.getStatusLine().getStatusCode() != 200) {
                throw new RuntimeException("Error : Código de error HTTP : " + response.getStatusLine().getStatusCode());
            }

            //Obtener información de la respuesta
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            System.out.println(factory);
            Document XMLDoc = factory.newDocumentBuilder().parse(response.getEntity().getContent());
            XPath xpath = XPathFactory.newInstance().newXPath();
            XPathExpression expr = xpath.compile("/AddToken2DBResponseType/Token");
            String result = String.class.cast(expr.evaluate(XMLDoc, XPathConstants.STRING));
            System.out.println("\nEl resultado es: " + result.length());
        }catch (Exception e) {
            e.printStackTrace();
        } finally {
            // Cierre de la conexión
            if (httpClient != null) httpClient.getConnectionManager().shutdown();
        }
    }
}

WSDL RESPONSE

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header/>
   <SOAP-ENV:Body>
      <ns2:AddToken2DBResponse xmlns:ns2="http://www.example.com/edit/example">
         <ns2:Token>u757Ric6542ytu6Ricgtr0</ns2:Token>
         <ns2:HandlerError>
            <ns2:statusCode>true</ns2:statusCode>
            <ns2:errorList>
               <ns2:error>
                  <ns2:code>OK</ns2:code>
                  <ns2:origin>JBOSS</ns2:origin>
                  <ns2:userMessage>Primer registro insertado</ns2:userMessage>
                  <ns2:developerMessage>Primer registro insertado</ns2:developerMessage>
               </ns2:error>
            </ns2:errorList>
         </ns2:HandlerError>
      </ns2:AddToken2DBResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

I appreciate your help

1
  • Instead of String.class.cast(x), you should use (String) x. The cast method should only be used when you don’t know the class to which you’re casting at compile-time. Commented Jan 10, 2017 at 19:37

1 Answer 1

2

Your XPath expression is wrong, if it starts with a single / it means that the element should be a/the root element (so obviously it will not find anything as the root element is SOAP-ENV:Envelope). So far it should be //AddToken2DBResponseType/Token.

Second issue is the namespace; you have two options (i am aware of):

  • parse it namespace aware and rewrite the xpath to be by tolerant towards the namespace.
  • parse it namespace unaware and use the namespace prefix in the xpath.

The second option is quite unstable so here is the first:

 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
 factory.setNamespaceAware(true);
 // ...
 XPathExpression expr = xpath.compile("//*[local-name='AddToken2DBResponseType']/*[local-name='Token']");

//*[local-name='abc'] Means any element that has a local-name (name without namespace) of abc (exactly what you want/need).

Sign up to request clarification or add additional context in comments.

3 Comments

There's another option: parse namespace aware and set the namespace context on the XPath to define your own prefix mappings.
@teppic Thanks did know about that option; does it work with XPath 1.* or does it need XPath 2?
It works with XPath 1. It's a bit fiddly tho'; there's no default implementation of NamespaceContext so it's necessary to add a dependency or write your own.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.