从Web服务获取响应时出错

时间:2013-05-02 13:55:28

标签: android web-services ksoap2

我创建了一个Android应用程序,它必须连接到一个Web服务(由我创建),它存储在一个数据库中(托管在免费托管的站点中)。网络服务会将latitudelongitudetext存储在数据库中,如果我使用它,它会很有效。

但我无法使用Android应用中的网络服务。 这是代码:

package com.example.mobile;

import java.io.IOException;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.os.AsyncTask;


public class WebServiceActivity extends Activity implements OnClickListener {

    public final static String SOAP_ACTION1 = "http://ocrwebservice.somee.com/InsertIntoDB";
    public final static String SOAP_ACTION2 = "http://ocrwebservice.somee.com/Testing";
    public final static String NAMESPACE = "http://ocrwebservice.somee.com/";
    public final static String METHOD_NAME1 = "InsertIntoDB";
    public final static String METHOD_NAME2 = "Testing";
    public final static String URL = "http://ocrwebservice.somee.com/Service1.asmx?WSDL";

    Bundle extras;
    TextView tvResult;
    Button btnMenu;
    String ocr;
    int test_or_train; //valore sentinella
    String gps, latitude, longitude;
    double latitudine, longitudine;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web_service);

        tvResult = (TextView)findViewById(R.id.textViewResult);
        btnMenu = (Button)findViewById(R.id.buttonGoToMenu);

        extras = getIntent().getExtras();
        ocr = extras.getString(RecognitionActivity.OCRTEXT);
        gps = extras.getString(RecognitionActivity.GPS);
        test_or_train = extras.getInt(RecognitionActivity.TEST_OR_TRAIN);

        String [] coordinate = gps.split("#");
        latitude = coordinate[0];
        longitude = coordinate[1];

        Log.d("VALORI", latitude);
        Log.d("VALORI", longitude);

        //latitudine = Double.parseDouble(latitude);
        //longitudine = Double.parseDouble(longitude);

        System.out.println(latitudine);
        System.out.println(longitudine);

        AsyncCallWS task = new AsyncCallWS();
        task.execute();

    }

    private class AsyncCallWS extends AsyncTask<Void,Void,Void>{
        @Override
        protected Void doInBackground(Void... params) {
            // TODO Auto-generated method stub
            perform();
            return null;
        }
    }

    void perform(){
        switch(test_or_train){
        case 0: //inserimento dei valori -- fase di training
            SoapObject requestInsert = new SoapObject(NAMESPACE, METHOD_NAME1);//inizializzazione richiesta SOAP e aggiunta parametri

            //aggiunta dei parametri per la richiesta SOAP      
            requestInsert.addProperty("latitudine", latitude);
            requestInsert.addProperty("longitudine", longitude);
            requestInsert.addProperty("testo", ocr);

            //dichiarazione della versione SOAP utilizzata
            SoapSerializationEnvelope insertEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
            insertEnvelope.setOutputSoapObject(requestInsert);
            insertEnvelope.dotNet = true;


            try {
                HttpTransportSE insertTransport = new HttpTransportSE(URL);

                //chiamata del web service
                insertTransport.call(SOAP_ACTION1, insertEnvelope);

                SoapPrimitive insertResult = (SoapPrimitive)insertEnvelope.getResponse();

                if(insertResult != null)
                    tvResult.setText(insertResult.toString());
                } catch (IOException e) {
                // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (XmlPullParserException e) {
                // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            break;

        case 1:
            SoapObject requestTest = new SoapObject(NAMESPACE, METHOD_NAME2);

            requestTest.addProperty("latitudine", latitudine);
            requestTest.addProperty("longitudine", longitudine);
            requestTest.addProperty("testo", ocr);

            SoapSerializationEnvelope testEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
            testEnvelope.setOutputSoapObject(requestTest);
            testEnvelope.dotNet = true;

            try{
                HttpTransportSE testTransport = new HttpTransportSE(URL);

                testTransport.call(SOAP_ACTION2, testEnvelope);

                SoapObject testResult = (SoapObject)testEnvelope.bodyIn;

                if(testResult != null){
                      if((testResult.getProperty(0).toString()).compareTo("EXISTS") == 0)
                        tvResult.setText("Il cartello fotografato è presente nel DB");
                    else
                        tvResult.setText("Attenzione! Il cartello fotografato non è presente nel DB");
                    }

                }catch (IOException e) {
                // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (XmlPullParserException e) {
                // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            break;

            }
        btnMenu.setOnClickListener(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_web_service, menu);
        return true;
    }

    @Override
    public void onClick(View arg0) {
        // TODO Auto-generated method stub
        Intent intentReset = new Intent(this,MainActivity.class);
        startActivity(intentReset);
    }
}

这是我得到的日志猫:

05-02 15:44:46.530: W/System.err(4670): SoapFault - faultcode: 'soap:Server' faultstring: 'Server was unable to process request. ---> You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''Po '')' at line 1' faultactor: 'null' detail: org.kxml2.kdom.Node@41934a08
05-02 15:44:46.530: W/System.err(4670):     at org.ksoap2.serialization.SoapSerializationEnvelope.parseBody(SoapSerializationEnvelope.java:141)
05-02 15:44:46.530: W/System.err(4670):     at org.ksoap2.SoapEnvelope.parse(SoapEnvelope.java:140)
05-02 15:44:46.540: W/System.err(4670):     at org.ksoap2.transport.Transport.parseResponse(Transport.java:116)
05-02 15:44:46.540: W/System.err(4670):     at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:259)
05-02 15:44:46.540: W/System.err(4670):     at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:114)

在调用SOAP方法时可能存在问题,但我不知道如何修复它。

1 个答案:

答案 0 :(得分:0)

您的代码似乎正在正确调用SOAP方法。问题出在Web服务本身上。

试试这个信封:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:ocr="http://ocrwebservice.somee.com/">
   <soapenv:Header/>
   <soapenv:Body>
      <ocr:InsertIntoDB>
         <ocr:latitudine>33</ocr:latitudine>
         <ocr:longitudine>44</ocr:longitudine>
         <ocr:testo>Po '</ocr:testo>
      </ocr:InsertIntoDB>
   </soapenv:Body>
</soapenv:Envelope>

你会发出同样的错误:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <soap:Body>
      <soap:Fault>
         <faultcode>soap:Server</faultcode>
         <faultstring>Server was unable to process request. ---> You have an
         error in your SQL syntax; check the manual that corresponds to your 
         MySQL server version for the right syntax to use near ''Po '')' at 
         line 1</faultstring>
         <detail/>
      </soap:Fault>
   </soap:Body>
</soap:Envelope>

另一方面,当您取出'时:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:ocr="http://ocrwebservice.somee.com/">
   <soapenv:Header/>
   <soapenv:Body>
      <ocr:InsertIntoDB>
         <ocr:latitudine>33</ocr:latitudine>
         <ocr:longitudine>44</ocr:longitudine>
         <ocr:testo>Po </ocr:testo>
      </ocr:InsertIntoDB>
   </soapenv:Body>
</soapenv:Envelope>

插入成功。

底线是:您的客户或您的网络服务必须正确转义'

我的意见?这应该在Web服务中完成,而不是在客户端中完成,因为不正确的转义会使您的服务容易受到SQL Injection的攻击。另外,PO '本身并不是无效的String,您的服务也不会因此而产生错误。