Ksoap2 空指针异常

Ksoap2 Nullpointer Exception

我有一个 Web 服务,它在 Tomcat 7.0.54(在我的本地机器上)上运行。它有两个方法,sayHelloFrom(String from),它应该 return 带有给定用户名的问候字符串。和 saveFile() 方法,它在调用时在我的本地机器上生成一个文件。 我还有 "standard" java 测试客户端用于此服务。 此外,我使用 this 一个远程网络服务进行测试。 现在我正在尝试使 KSOAP2 android 客户端成为我的网络服务。 所以。当我调用我的网络服务时,使用 "standard" java 客户端 - 一切正常。 当我使用 KSOAP2 android 客户端调用远程网络服务时,也没有问题。 但是,当我用 android KSOAP2 客户端调用我的网络服务时,我在 envelope.getResponse() 操作上得到 NullPointerException,同时,网络服务本身,被调用,文件被生成并且在 web 服务的堆栈跟踪中没有错误:

这是错误堆栈跟踪:

05-26 17:19:33.900  30066-30340/my.test.ru.app E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #2
    java.lang.RuntimeException: An error occured while executing doInBackground()
            at android.os.AsyncTask.done(AsyncTask.java:278)
            at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
            at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
            at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
            at java.util.concurrent.FutureTask.run(FutureTask.java:137)
            at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:208)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
            at java.lang.Thread.run(Thread.java:856)
     Caused by: java.lang.NullPointerException
            at activity.my.test.ru.WebService$myAsyncTask.doInBackground(WebService.java:84)
            at activity.my.test.ru.WebService$myAsyncTask.doInBackground(WebService.java:38)
            at android.os.AsyncTask.call(AsyncTask.java:264)
            at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
            at java.util.concurrent.FutureTask.run(FutureTask.java:137)
            at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:208)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
            at java.lang.Thread.run(Thread.java:856)

这是我的 android activity 调用网络服务:

public class WebService extends Activity {
    private final String NAMESPACE = "http://example";
    private final String URL = "http://192.168.1.88:8080/services/HelloWorld?wsdl";
    private final String SOAP_ACTION = "http://example/saveFile";
    private final String METHOD_NAME = "saveFile";
    Button b;
    private TextView tv;
    private String response;

    private class myAsyncTask extends AsyncTask<Void, Void, Void> {


        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            tv.setText(response);
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected Void doInBackground(Void... arg0) {
            SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
            //request.addProperty("from", "Naseko");
            //request.addProperty("iTopN", "5");
            SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
            envelope.setOutputSoapObject(request);

            HttpTransportSE httpTransport = new HttpTransportSE(URL);

            httpTransport.debug = true;
            try {
                httpTransport.call(SOAP_ACTION, envelope);
            } catch (HttpResponseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (XmlPullParserException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } //send request
            SoapObject result = null;
            try {
                result = (SoapObject) envelope.getResponse();
                Log.d("App", "" + result);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            Log.d("App", "" + result.getProperty(1).toString());
            response = result.getProperty(1).toString();
            return null;
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web_service);
        //Fahrenheit Text control
        tv = (TextView) findViewById(R.id.tv_result);
        //Button to trigger web service invocation
        b = (Button) findViewById(R.id.button1);
        //Button Click Listener
        b.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                myAsyncTask myRequest = new myAsyncTask();
                myRequest.execute();
            }
        });
    }
}

以及来自清单的许可:

   <uses-permission android:name="android.permission.GET_ACCOUNTS"/> 
   <uses-permission android:name="android.permission.READ_PROFILE"/> 
   <uses-permission android:name="android.permission.READ_CONTACTS"/> 
   <uses-permission android:name="android.permission.INTERNET"/>
   <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
   <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

这是我的 WSDL:

<wsdl:definitions xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://example" xmlns:intf="http://example" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://example">
<!--
WSDL created by Apache Axis version: 1.4
Built on Apr 22, 2006 (06:55:48 PDT)
-->
<wsdl:types>
<schema xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://example">
<element name="saveFileReturn" type="xsd:string"/>
<element name="from" type="xsd:string"/>
<element name="sayHelloWorldFromReturn" type="xsd:string"/>
</schema>
</wsdl:types>
<wsdl:message name="saveFileRequest"></wsdl:message>
<wsdl:message name="saveFileResponse">
<wsdl:part element="impl:saveFileReturn" name="saveFileReturn"/>
</wsdl:message>
<wsdl:message name="sayHelloWorldFromResponse">
<wsdl:part element="impl:sayHelloWorldFromReturn" name="sayHelloWorldFromReturn"/>
</wsdl:message>
<wsdl:message name="sayHelloWorldFromRequest">
<wsdl:part element="impl:from" name="from"/>
</wsdl:message>
<wsdl:portType name="HelloWorld">
<wsdl:operation name="saveFile">
<wsdl:input message="impl:saveFileRequest" name="saveFileRequest"/>
<wsdl:output message="impl:saveFileResponse" name="saveFileResponse"/>
</wsdl:operation>
<wsdl:operation name="sayHelloWorldFrom" parameterOrder="from">
<wsdl:input message="impl:sayHelloWorldFromRequest" name="sayHelloWorldFromRequest"/>
<wsdl:output message="impl:sayHelloWorldFromResponse" name="sayHelloWorldFromResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="HelloWorldSoapBinding" type="impl:HelloWorld">
<wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="saveFile">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="saveFileRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="saveFileResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="sayHelloWorldFrom">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="sayHelloWorldFromRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="sayHelloWorldFromResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="HelloWorldService">
<wsdl:port binding="impl:HelloWorldSoapBinding" name="HelloWorld">
<wsdlsoap:address location="http://192.168.1.88:8080/services/HelloWorld"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

这是我的网络服务代码:

@WebService
public class HelloWorld {
    @WebMethod
    public String sayHelloWorldFrom(String from) {
        String result = "Hello, world, from " + from;
        System.out.println(result);
        return result;
    }

    @WebMethod
    public String saveFile() {
        try {
            String content = "This is the content to write into file";
            File file = new File("C:\test\filename.txt");
            // if file doesnt exists, then create it
            if (!file.exists()) {
                file.createNewFile();
            }

            FileWriter fw = new FileWriter(file.getAbsoluteFile());
            BufferedWriter bw = new BufferedWriter(fw);
            bw.write(content);
            bw.close();
            System.out.println("Done!!!");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "OK";
    }
}

知道了!

首先,我将 doInBackground 中的所有内容都放入 try 块中。 然后我得到了新的 ecxeption,它是 classCastException。 因此,获取结果的代码行我更改为:

            SoapPrimitive result =(SoapPrimitive)envelope.bodyIn;
            Log.d("App", "" + result.toString());
            response = result.toString();

洞 doInBackground 方法现在看起来像这样:

    @Override
    protected Void doInBackground(Void... arg0) {
        try {
            SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
            SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
            envelope.setOutputSoapObject(request);
            HttpTransportSE httpTransport = new HttpTransportSE(URL);
            //httpTransport.debug = true;
            httpTransport.call(SOAP_ACTION, envelope);
            SoapPrimitive result =(SoapPrimitive)envelope.bodyIn;
            Log.d("App", "" + result.toString());
            response = result.toString();
        } catch (IOException | XmlPullParserException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }  //send request
        return null;
    }
}