我创建了一个Android应用程序,它必须连接到一个Web服务(由我创建),它存储在一个数据库中(托管在免费托管的站点中)。网络服务会将latitude
,longitude
和text
存储在数据库中,如果我使用它,它会很有效。
但我无法使用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方法时可能存在问题,但我不知道如何修复它。
答案 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
,您的服务也不会因此而产生错误。