Search code examples
javaandroidandroid-ksoap2

Get exception class in kSoap2 on Android


I've got a fault message. I've successfully caught it on Android. What I would like now, is to get the Class for the Exception that triggered the fault. The message goes like this:

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
   <S:Body>
      <S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
         <faultcode>S:Server</faultcode>
         <faultstring>Error retrieving user`s [..]</faultstring>
         <detail>
            <ns2:exception class="com.example.UserException_Exception" note="To disable this feature, set com.sun.xml.ws.fault.SOAPFaultBuilder.disableCaptureStackTrace system property to false" xmlns:ns2="http://jax-ws.dev.java.net/">
               <message>EError retrieving user`s [..]</message>
               <ns2:stackTrace>
                  <ns2:frame class="sun.reflect.DelegatingMethodAccessorImpl" file="DelegatingMethodAccessorImpl.java" line="43" method="invoke"/>
                  <ns2:frame class="java.lang.reflect.Method" file="Method.java" line="601" method="invoke"/>
                  <ns2:frame class="com.sun.xml.ws.api.server.InstanceResolver$1" file="InstanceResolver.java" line="246" method="invoke"/>
                  <ns2:frame class="com.sun.xml.ws.server.InvokerTube$2" file="InvokerTube.java" line="146" method="invoke"/>
                  <ns2:frame class="com.sun.xml.ws.server.sei.EndpointMethodHandler" file="EndpointMethodHandler.java" line="257" method="invoke"/>
                  <ns2:frame class="com.sun.xml.ws.server.sei.SEIInvokerTube" file="SEIInvokerTube.java" line="95" method="processRequest"/>
                  <ns2:frame class="com.sun.xml.ws.api.pipe.Fiber" file="Fiber.java" line="629" method="__doRun"/>
                  <ns2:frame class="com.sun.xml.ws.api.pipe.Fiber" file="Fiber.java" line="588" method="_doRun"/>
                  <ns2:frame class="com.sun.xml.ws.api.pipe.Fiber" file="Fiber.java" line="573" method="doRun"/>
                  <ns2:frame class="com.sun.xml.ws.api.pipe.Fiber" file="Fiber.java" line="470" method="runSync"/>
                  <ns2:frame class="com.sun.xml.ws.server.WSEndpointImpl$2" file="WSEndpointImpl.java" line="295" method="process"/>
                  <ns2:frame class="com.sun.xml.ws.transport.http.HttpAdapter$HttpToolkit" file="HttpAdapter.java" line="515" method="handle"/>
                  <ns2:frame class="com.sun.xml.ws.transport.http.HttpAdapter" file="HttpAdapter.java" line="285" method="handle"/>
                  <ns2:frame class="com.sun.xml.ws.transport.http.servlet.ServletAdapter" file="ServletAdapter.java" line="143" method="handle"/>
                  <ns2:frame class="com.sun.xml.ws.transport.http.servlet.WSServletDelegate" file="WSServletDelegate.java" line="155" method="doGet"/>
                  <ns2:frame class="java.lang.Thread" file="Thread.java" line="722" method="run"/>
               </ns2:stackTrace>
            </ns2:exception>
         </detail>
      </S:Fault>
   </S:Body>
</S:Envelope>

I've removed a part of the trace, because it is not relevant.

This is the code' im using for the transaction:

public static Long getCount(String id)
            throws XmlPullParserException, IOException {

        SoapObject request = new SoapObject(NAMESPACE, "getCount");
        request.addProperty("id", id);

        SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(
                SoapEnvelope.VER11);
        soapEnvelope.dotNet = true;

        soapEnvelope.setOutputSoapObject(request);

        System.setProperty("http.keepAlive", "false");

        HttpTransportSE htse = new HttpTransportSE(URL);

        htse.call(URL, soapEnvelope, null);

        SoapPrimitive response = (SoapPrimitive) soapEnvelope.getResponse();
        Long count = null;
        try {
            timestampCount = Long.parseLong(response.toString());
        } catch (NumberFormatException e) {
            e.printStackTrace();
        } catch (SoapFault e) {
            e.printStackTrace();
        }


        return count;
    }

So, how do I go about getting class="com.ltc.mid.pdf.UserCertificateException_Exception" from the SoapFault object?

Just to be perfectly clear: I'm looking for either:

  • Java code to get the class atribute from <detail><exception> element
  • SOAP parsing code to get class atribute from <detail><exception> element

Thanks!


Solution

  • I managed to solve this myself.

    So, taking the format displayed in the question into consideration, this is what works for me:

    soapEnvelope.setOutputSoapObject(request);
    
            System.setProperty("http.keepAlive", "false");
    
            HttpTransportSE htse = new HttpTransportSE(URL, 60000);
    
            //htse.debug=true; //This directive is helpful while debugging
            try {
                htse.call(URL, soapEnvelope, null);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (XmlPullParserException e) {
                e.printStackTrace();
            }
            if (soapEnvelope.bodyIn instanceof SoapFault) {
                Node details = ((SoapFault) soapEnvelope.bodyIn).detail;
                Element detailElem = (Element) details.getElement(0).getChild(0);
                String exc = detailElem.getName();
                if (exc.equals("SomeSpecificException")) {
                    throw new SomeSpecificException();
                }
                throw new Exception("SOAP PROBLEMS!");
            }