J'ai un problème lors de l'appel d'un service Web. J'ai un service Web .NET sur le serveur et j'utilise KSOAP2 (ksoap2-j2se-full-2.1.2) sous Android. Lors de l'exécution du programme, j'ai eu une exception d'exécution telle que "org.ksoap2.serialization.SoapPrimitive". Que devrais-je faire?
Voici mon code.
package projects.ksoap2sample;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import Android.app.*;
import Android.os.*;
import Android.widget.TextView;
public class ksoap2sample extends Activity {
/** Called when the activity is first created. */
private static final String SOAP_ACTION = "http://tempuri.org/HelloWorld";
private static final String METHOD_NAME = "HelloWorld";
private static final String NAMESPACE = "http://tempuri.org/";
private static final String URL = "http://192.168.1.19/TestWeb/WebService.asmx";
TextView tv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv=(TextView)findViewById(R.id.text1);
try {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
//request.addProperty("prop1", "myprop");
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet=true;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.call(SOAP_ACTION, envelope);
Object result = (Object)envelope.getResponse();
String[] results = (String[]) result;
tv.setText( ""+results[0]);
}
catch (Exception e) {
tv.setText(e.getMessage());
}
}
}
C'est très simple. Vous obtenez le résultat dans une variable Object
qui est primitive.
Votre code:
Object result = (Object)envelope.getResponse();
Code correct:
SoapObject result=(SoapObject)envelope.getResponse();
//To get the data.
String resultData=result.getProperty(0).toString();
// 0 is the first object of data.
Je pense que cela devrait certainement fonctionner.
Comment se présente votre Webservice .NET?
J'ai eu le même effet en utilisant ksoap 2.3 de code.google.com . J'ai suivi le tutoriel sur Le projet de code
Et chaque fois que j'ai utilisé
Integer result = (Integer)envelope.getResponse();
pour obtenir le résultat d'un mon service Web (quel que soit le type, j'ai essayé Object, String, int), j'ai rencontré l'exception org.ksoap2.serialization.SoapPrimitive
.
J'ai trouvé une solution (solution de contournement). La première chose à faire était de supprimer l'attribut "SoapRpcMethod ()" de mes méthodes de service Web.
[SoapRpcMethod(), WebMethod]
public Object GetInteger1(int i)
{
// Android device will throw exception
return 0;
}
[WebMethod]
public Object GetInteger2(int i)
{
// Android device will get the value
return 0;
}
Puis j'ai changé mon code Android en:
SoapPrimitive result = (SoapPrimitive)envelope.getResponse();
Cependant, je reçois un objet SoapPrimitive, qui a une "valeur" classée qui est privée. Heureusement, la valeur est transmise par la méthode toString()
. J'utilise donc Integer.parseInt(result.toString())
pour obtenir ma valeur, ce qui me suffit, car je n'ai aucun type complexe à obtenir de mon service Web.
Voici la source complète:
private static final String SOAP_ACTION = "http://tempuri.org/GetInteger2";
private static final String METHOD_NAME = "GetInteger2";
private static final String NAMESPACE = "http://tempuri.org/";
private static final String URL = "http://10.0.2.2:4711/Service1.asmx";
public int GetInteger2() throws IOException, XmlPullParserException {
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
PropertyInfo pi = new PropertyInfo();
pi.setName("i");
pi.setValue(123);
request.addProperty(pi);
SoapSerializationEnvelope envelope =
new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(URL);
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapPrimitive result = (SoapPrimitive)envelope.getResponse();
return Integer.parseInt(result.toString());
}
Typecast l'enveloppe à SoapPrimitive:
SoapPrimitive result = (SoapPrimitive)envelope.getResponse();
String strRes = result.toString();
et ça va marcher.
Vous pouvez utiliser le code ci-dessous pour appeler le service Web et obtenir une réponse. Assurez-vous que votre service Web renvoie la réponse sous Format de table de données .. Ce code vous aidera si vous utilisez des données de SQL Server database. Si vous utilisezMYSQLvous devez changer quelque chose, il suffit de remplacer Word NewDataSet à partir de la phrase obj2=(SoapObject) obj1.getProperty("NewDataSet");
par DocumentElement
private static final String NAMESPACE = "http://tempuri.org/";
private static final String URL = "http://localhost/Web_Service.asmx?"; // you can use IP address instead of localhost
private static final String METHOD_NAME = "Function_Name";
private static final String SOAP_ACTION = NAMESPACE + METHOD_NAME;
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("parm_name", prm_value); // Parameter for Method
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try {
androidHttpTransport.call(SOAP_ACTION, envelope); //call the eb service Method
} catch (Exception e) {
e.printStackTrace();
} //Next task is to get Response and format that response
SoapObject obj, obj1, obj2, obj3;
obj = (SoapObject) envelope.getResponse();
obj1 = (SoapObject) obj.getProperty("diffgram");
obj2 = (SoapObject) obj1.getProperty("NewDataSet");
for (int i = 0; i < obj2.getPropertyCount(); i++) //the method getPropertyCount() return the number of rows
{
obj3 = (SoapObject) obj2.getProperty(i);
obj3.getProperty(0).toString(); //value of column 1
obj3.getProperty(1).toString(); //value of column 2
//like that you will get value from each column
}
Si vous avez un problème à ce sujet, vous pouvez m'écrire ..
Je pense que tu ne peux pas appeler
androidHttpTransport.call(SOAP_ACTION, envelope);
sur le fil principal.
Les opérations réseau doivent être effectuées sur différents threads.
Créez un autre thread ou une tâche asynchrone pour appeler la méthode.
Si plusieurs résultats sont attendus, la méthode getResponse()
renverra une Vector
contenant les différentes réponses.
Dans ce cas, le code incriminé devient:
Object result = envelope.getResponse();
// treat result as a vector
String resultText = null;
if (result instanceof Vector)
{
SoapPrimitive element0 = (SoapPrimitive)((Vector) result).elementAt(0);
resultText = element0.toString();
}
tv.setText(resultText);
Réponse basée sur le ksoap2-Android (mosabua fork)