Mehmet Ethem SULAN :: Android :: Using KSOAP2 for android, and parsing SOAP WSDL output data

Android ile KSOAP2 kullanarak SOAP Web Serviceden data çekmeye çalışırken karşılaştığım sorunu çözdükten sonra paylaşmaya çalıştım. En önemli sorun When Parsing the Soap response problem Android Developer grubuna sorulan sorudur. Kod içinde

Log.e(">>>>>>>>>>>>>>>>>>", "Root elemtn body: "+soapObjectResultRoot.toString());

satırındaki outputa bakarsanız hiçbir formata uymayan bir data var ve o datayı parse etmek indexOf() metodu ile ancak yapılabiliyordu. DDMS e bakarsanız

Root elemtn body: GetGeoIPContextResponse{GetGeoIPContextResult=anyType{ReturnCode=1; IP=78.175.34.228; ReturnCodeDetails=Success; CountryName=Turkey; CountryCode=TUR; }; }

şeklinde saçma bir data görürsünüz. Bunun sebebi bodyIn ile sadece Root Element alınmasıdır. Yani çözüm önce rootu almak sonra istenilen result metodunundaki propertye erişmektir.

        	SoapObject soapObjectResultRoot=(SoapObject) soaSerializationEnvelope.bodyIn;
        	Log.e(">>>>>>>>>>>>>>>>>>", "Root elemtn body: "+soapObjectResultRoot.toString());
        	SoapObject soapObjectGetProperty=(SoapObject) soapObjectResultRoot.getProperty("GetGeoIPContextResult");

Bu linkte-GetGeoIPContext hangi metodu ve getProperty() ile hangi değerlere erişeceğimizi SOAP içinde yazıyor.
Uyarı örnek yapacağınız web servisi önce çalışıp çalışmadığını kontrol edin. Mesela şu anda Translation Engine çalışmıyor ve ben de bunun üzerinden deneme yapıyordum 🙂
1. ksoap2-android-assembly-2.4-jar-with-dependencies.jar indirdikten sonra assets içine atıp sonra sağ tıklayıp Build path->Add to build path tıklamanız yeterlidir. Ya da lib isminde bir klasör oluşturup onun altında atıp aynı şekilde sağ tıklayıp Build path->Add to build path ekletebilirisniz.
2. Erişeceğiniz http://www.webservicex.net/geoipservice.asmx?WSDL deki WSDL silip var olan public metodlarını iyice incelemektir. Sonra istediğinizi kullanabilirisniz.
3. AndroidManifest.xml içinde

<uses-permission android:name="android.permission.INTERNET"/>

ekleyin.

AndroidSoapActivity.java

package com.androidsoap;

import java.io.IOException;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.SoapFault;
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.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class AndroidSoapActivity extends Activity {

	final static String NAMESPACE = "http://www.webservicex.net/";
	final static String METHOD_NAME = "GetGeoIPContext";
	final static String SOAP_ACTION = "http://www.webservicex.net/GetGeoIPContext";
	final static String URL = "http://www.webservicex.net/geoipservice.asmx?WSDL";
	
	TextView textView;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        textView=(TextView) findViewById(R.id.textView1);
        SoapObject reSoapObject = new SoapObject(NAMESPACE, METHOD_NAME);
//Egerki sorgu çekecekseniz o zaman reSoapObject.addProperty(name,value); şeklinde değer eklemelisiniz. O da SOAP içinde belirtiliyor.
        SoapSerializationEnvelope soaSerializationEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);

        soaSerializationEnvelope.dotNet = true;
        soaSerializationEnvelope.setOutputSoapObject(reSoapObject);
        HttpTransportSE httpTransportSE = new HttpTransportSE(URL);
        int returnCode = 0;
        String ip = null, returnCodeDetail = null,countryName = null, countryCode = null;
        try {
        	httpTransportSE.call(SOAP_ACTION, soaSerializationEnvelope);
//Root elemente erişiyoruz.
        	SoapObject soapObjectResultRoot=(SoapObject) soaSerializationEnvelope.bodyIn;
        	Log.e(">>>>>>>>>>>>>>>>>>", "Root elemtn body: "+soapObjectResultRoot.toString());
//Root elementin altındaki erişeceğimiz metodun ..Result ile biten değerine erişiyoruz. Mesela METHOD_NAME = "GetGeoIPContext";
//Aşağıdaki metod ve parametre değerleri bulinkte açıklıyor zaten: http://www.webservicex.net/geoipservice.asmx?op=GetGeoIPContext
        	SoapObject soapObjectGetProperty=(SoapObject) soapObjectResultRoot.getProperty("GetGeoIPContextResult");
        	returnCode=Integer.parseInt(soapObjectGetProperty.getProperty("ReturnCode").toString());
        	ip=soapObjectGetProperty.getProperty("IP").toString();
        	returnCodeDetail=soapObjectGetProperty.getProperty("ReturnCodeDetails").toString();
        	countryName=soapObjectGetProperty.getProperty("CountryName").toString();
        	countryCode=soapObjectGetProperty.getProperty("CountryCode").toString();
        } catch (IOException e) {
        e.printStackTrace();
        } catch (XmlPullParserException e) {
        e.printStackTrace();
        }
        
        textView.setText("Return code --> "+returnCode+" nIP --> "+ip+" nReturn code details --> "+returnCodeDetail+" nCountry name --> "+countryName+" nCountry code --> "+countryCode);
        
    
    }
}

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="230dp"
        android:layout_height="wrap_content"
        android:text="TextView" />

</LinearLayout>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.androidsoap"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="4" />
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name=".AndroidSoapActivity" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Download AndroidSoapSam.zip srouce code

Comments

There are 5 comments for this post.

  1. Serhat on Kasım 15, 2011 8:38 am

    Merhabalar, öncelikle bu güzel deneyimlerini bizlerle paylaştığın için teşekkürler.
    Son günlerde push notification (C2DM) ile uğraşıyorum. Yaptım ama biraz zorlandım açıkcası. Bu konuda bir deneyimin varsa ve paylaşırsan insanlık adına büyük iyilik yapmış olursun 🙂 ne yazık ki blog yazmak için yeterli vaktim yok. keşke olsa da böyle güzel şeyler yapabilsem

  2. krishnaveni on Mart 3, 2012 5:08 am

    Hi i am also done ur above example.but am getting dis error.how it is cleared.the error is Returncode–>0 nIP–>null nReturnCodeDetails–>null nCountryName–>null nCountryCode–>null…How it is cleared…plx help me

  3. tyfn on Mayıs 26, 2012 9:17 am

    Eyvallah hocam, çok işe yaradı bu.

  4. krishnaveni on Haziran 15, 2012 9:22 am
  5. osman on Temmuz 11, 2013 8:40 pm

    Proje dosyası içerisindeki *.apk çalışıyor, yeni proje oluşuturup kod bloklarını eklersem çalışmıyor. 2.3.3e göre derleme yapıyorum sıkıntı bundan mıdır?

Write a Comment

Let me know what you think?