android調用web service(cxf)實例

android調用web service(cxf)實例

Googlendroid平臺開發Web Service提供了支持,提供了Ksoap2-android相關架包

1.下載該夾包可以直接登錄http://code.google.com/p/ksoap2-android/,現在該站點已經提供了直接的下載,只要點擊下載鏈接就可以下載了;

我現在的是ksoap2-android-assembly-2.6.5-jar-with-dependencies.jar

2.好了,現在我們就可以進行新建項目來進行測試了,首先我們先建立java服務端,這裏的一些前期準備我就不說了(比如與spring的整合等示例),

如果有不清楚的可以去看博客 http://www.cnblogs.com/shenliang123/archive/2012/04/16/2451580.html

由於這裏重點是android客戶端,java服務器端就直接給代碼了

Interface:(這裏提供了兩個方法,一個傳遞的是簡單字符串,另一個傳遞的是符合對象+集合)

package xidian.sl.service.webService;

 

import javax.jws.WebParam;

import javax.jws.WebService;

import javax.jws.soap.SOAPBinding;

import javax.jws.soap.SOAPBinding.Style;

 

import xidian.sl.service.impl.webService.StudentList;

 

@WebService

@SOAPBinding(style = Style.RPC)

publicinterface TestService {

    public String getUser(@WebParam(name = "name")String name);

    public StudentList getStuList();

}   

implement:

package xidian.sl.service.impl.webService;

 

import java.util.ArrayList;

import java.util.List;

 

import javax.jws.WebService;

 

import xidian.sl.entity.Students;

import xidian.sl.service.webService.TestService;

 

@WebService(endpointInterface = "xidian.sl.service.webService.TestService")

publicclassTestServiceImpl implements TestService {

 

    @Override

    public String getUser(String name) {

        System.out.println("客戶端傳遞的名字爲 = "+name);

        return name;

    }

 

    @Override

    public StudentList getStuList() {

        System.out.println("該方法被調用");

        List<Students> stuList = new ArrayList<Students>();

        //第一個學生

        Students stu1 = new Students();

       stu1.setStuName("沈浪");

        stu1.setStuNum("1006010054");

        stu1.setStuSex("");

        stuList.add(stu1);

        //第二個學生

        Students stu2 = new Students();

        stu2.setStuName("香香");

        stu2.setStuNum("1006010043");

        stu2.setStuSex("");

        stuList.add(stu2);

        //List集合封裝成一個對象才能在webService中進行傳遞

        StudentList studentList = new StudentList();

        studentList.setStuList(stuList);

        return studentList;

    }

 

}

list的封裝對象

package xidian.sl.service.impl.webService;

 

import java.util.List;

 

import xidian.sl.entity.Students;

 

publicclass StudentList{

    private List<Students> stuList;

 

    public List<Students> getStuList() {

        return stuList;

    }

 

    publicvoid setStuList(List<Students> stuList) {

        this.stuList = stuList;

    }

   

}   

然後在srping的整合配置文件中進行如下配置即可(默認web.xml中已經進行配置)

<?xml version="1.0" encoding="UTF-8"?>

        <beans xmlns="http://www.springframework.org/schema/beans"

        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

        xmlns:jaxws="http://cxf.apache.org/jaxws"

        xsi:schemaLocation="

               http://www.springframework.org/schema/beans

               http://www.springframework.org/schema/beans/spring-beans.xsd

               http://www.springframework.org/schema/context

                http://www.springframework.org/schema/context/spring-context.xsd

                http://cxf.apache.org/jaxws

               http://cxf.apache.org/schemas/jaxws.xsd">

       

                <import resource="classpath:META-INF/cxf/cxf.xml"/>  <!-- 這些xml文件在cxf-2.5.0.jarMETA-INF目錄下-->

                <!--<importresource="classpath:META-INF/cxf/cxf-extension-soap.xml" />

                        警告提示已經廢棄了cxf-extension-soap.xml文件-->

                <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>

 

               

                <!-- 這裏配置服務接口,後面描述

               

                    id:指在spring配置的beanID.

 

                    Implementor:指明具體的實現類.

 

                    Address:指明這個web service的相對地址

                 -->

 

                      <!-- 測試 -->

                      <bean id="testServiceImpl" class="xidian.sl.service.impl.webService.TestServiceImpl">

                      </bean>

                    <jaxws:endpoint id="testService"

                            implementor="#testServiceImpl"

                            address="/test"/>

                     

                  <!-- 開啓tomcat服務器,訪問http://localhost:8080/WebExam/services/test?wsdl

                     http://localhost:8080/WebExam是本項目的訪問地址

 

                    services是由於web.xml配置所得,test是由於Spring配置文件中的address屬性所得

                 

                  -->

                  

        </beans>

 

       

3.到此服務器端的已經建立完全,我們可以測試下:開啓tomcat,然後在瀏覽器中輸入http://localhost:8090/WebExam/services/test?wsdl可以查看wsdl


現在我們就可以開始建立android客戶端了

新建一個項目後導入ksoap2-android-assembly-2.6.5-jar-with-dependencies.jar這裏要特別注意:導入包的方式不要選擇項目右鍵---->buildpath---->

add external archives...,如果使用這種方式表面上好像是導入了包,但還是沒有辦法引用到,然後啓動項目後一直會報

我們還是選擇和開發web一樣的方式,就是在項目下新建lib或者libs文件夾,然後將jar直接複製到該文件夾中,IDE會幫助直接引入的

這樣就正確無誤了,不再會報類無法引用到了

android中通過webservice調用服務器端其實還是很簡單的,只要按部就班的按照下面步驟進行即可:

1)創建HttpTransportSE對象,該對象用於調用WebService操作

HttpTransportSE ht = newHttpTransportSE(SERVICE_URL);

2)創建SoapSerializationEnvelope對象

 SoapSerializationEnvelope envelope = newSoapSerializationEnvelope(SoapEnvelope.VER11);

3)創建SoapObject對象,創建該對象時需要傳入所要調用的Web Service的命名空間和WebService方法名

SoapObject request = newSoapObject(SERVICE_NS, methodName);

4)如果有參數傳給Web Service服務器端,調用SoapObject對象的addProperty(String name, Object value)方法來設置參數,該方法的name參數指定參數名

  注意:參數名不一定要與服務端的方法中的參數名相同,只要對應順序相同即可;value參數指定參數值

request.addProperty("name","1006010054");

5)調用SoapSerializationEnvelopesetOutputSoapObject()方法,或者直接對bodyOut屬性賦值,將前兩步創建的SoapObject對象設爲SoapSerializationEnvelope

  的傳出SOAP消息體

 envelope.bodyOut = request;

6)調用對象的call()方法,並以SoapSerializationEnvelope作爲參數調用遠程的web service

ht.call(null, envelope);

7)掉用完成後,訪問SoapSerializationEnvelope對象的bodyIn屬性,該屬性返回一個SoapObject對象,該對象就代表Web service的返回消息,解析該對象,即可獲得

  調用web service的返回值

SoapObject result = (SoapObject) envelope.bodyIn;

                String name = result.getProperty(0).toString();

下面給書具體的實例:
mian.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:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:text="@string/hello"/>

 

    <EditText

        android:id="@+id/editText1"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:ems="10">

 

        <requestFocus />

    </EditText>

 

    <EditText

        android:id="@+id/editText2"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:ems="10"/>

 

</LinearLayout>

Activity:(該Activity調用了服務器端返回普通字符串的方法)

package xidian.sl.android.webservice;

 

import org.ksoap2.SoapEnvelope;

import org.ksoap2.serialization.SoapObject;

import org.ksoap2.serialization.SoapSerializationEnvelope;

import org.ksoap2.transport.HttpTransportSE;

 

import android.app.Activity;

import android.os.Bundle;

import android.widget.EditText;

 

publicclass WebServiceSimpleDemoextends Activity{

    finalstatic String SERVICE_NS ="http://webService.service.sl.xidian/";

    finalstatic String SERVICE_URL ="http://192.168.1.103:8090/WebExam/services/test";

    private EditText txt1;

    private EditText txt2;

    /** Calledwhen the activity is first created. */

    @Override

    publicvoid onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        txt1 = (EditText) findViewById(R.id.editText1);

        txt2 = (EditText) findViewById(R.id.editText2);

        //調用的方法

        String methodName = "getUser";

        //創建httpTransportSE傳輸對象

        HttpTransportSE ht = newHttpTransportSE(SERVICE_URL);

        ht.debug = true;

        //使用soap1.1協議創建Envelop對象

        SoapSerializationEnvelope envelope = newSoapSerializationEnvelope(SoapEnvelope.VER11);

        //實例化SoapObject對象

        SoapObject request = newSoapObject(SERVICE_NS, methodName);

        /**

         * 設置參數,參數名不一定需要跟調用的服務器端的參數名相同,只需要對應的順序相同即可

         * */

        request.addProperty("name", "1006010054");

        //SoapObject對象設置爲SoapSerializationEnvelope對象的傳出SOAP消息

        envelope.bodyOut = request;

        try{

            //調用webService

            ht.call(null, envelope);

            //txt1.setText("看看"+envelope.getResponse());

            if(envelope.getResponse() != null){

                txt2.setText("有返回");

                SoapObject result = (SoapObject)envelope.bodyIn;

                String name = result.getProperty(0).toString();

                txt1.setText("返回值 = "+name);

            }else{

                txt2.setText("無返回");

            }

        }catch (Exception e) {

            e.printStackTrace();

        }

    }

}

AndroidManifest.xml進行Activity的註冊和並添加訪問網絡的權限

<?xml version="1.0"encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="xidian.sl.android.webservice"

    android:versionCode="1"

    android:versionName="1.0">

 

    <uses-sdk android:minSdkVersion="10"/>

 

    <application

        android:icon="@drawable/ic_launcher"

        android:label="@string/app_name">

        <activity

            android:name=".WebServiceSimpleDemo"

            android:label="@string/app_name">

            <intent-filter>

                <action android:name="android.intent.action.MAIN"/>

 

                <category android:name="android.intent.category.LAUNCHER"/>

            </intent-filter>

        </activity>

    </application>

    <!-- 聲明該應用自身所擁有的權限 -->

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

</manifest>

運行後的結果如圖所示:

下面我們來試着調用回傳符合對象的方法:

activity:

package xidian.sl.android.webservice;

 

import org.ksoap2.SoapEnvelope;

import org.ksoap2.serialization.SoapObject;

import org.ksoap2.serialization.SoapSerializationEnvelope;

import org.ksoap2.transport.HttpTransportSE;

 

import android.app.Activity;

import android.os.Bundle;

import android.widget.EditText;

 

publicclassWebServiceComplexDemo extends Activity{

    finalstatic String SERVICE_NS ="http://webService.service.sl.xidian/";

finalstatic String SERVICE_URL =

    "http://192.168.1.103:8090/WebExam/services/test";

    private EditText txt1;

    private EditText txt2;

    /** Calledwhen the activity is first created. */

    @Override

    publicvoid onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        txt1 = (EditText) findViewById(R.id.editText1);

        txt2 = (EditText) findViewById(R.id.editText2);

        //調用的方法

        String methodName ="getStuList";

        //創建httpTransportSE傳輸對象

        HttpTransportSE ht = newHttpTransportSE(SERVICE_URL);

        ht.debug = true;

        //使用soap1.1協議創建Envelop對象

        SoapSerializationEnvelope envelope = new         

        SoapSerializationEnvelope(SoapEnvelope.VER11);

        //實例化SoapObject對象

        SoapObject request = newSoapObject(SERVICE_NS, methodName);

        /**

         * 設置參數,參數名不一定需要跟調用的服務器端的參數名相同,只需要對應的順序相同即可

         * */

        //request.addProperty("name", "1006010054");

        //SoapObject對象設置爲SoapSerializationEnvelope對象的傳出SOAP消息

        envelope.bodyOut = request;

        try{

            //調用webService

            ht.call(null, envelope);

            txt2.setText("回傳的值"+envelope.getResponse());

            if(envelope.getResponse() != null){

                SoapObject result = (SoapObject)envelope.bodyIn;

                SoapObject soapChilds = (SoapObject)result.getProperty(0);

                StringBuffer sb = new StringBuffer();

                for(int   i=0; i<soapChilds.getPropertyCount(); i++){

                    SoapObject soapChildsChilds=(SoapObject)soapChilds.getProperty(i);

                    sb.append("姓名["+i+"] ="+soapChildsChilds.getProperty(0).toString()+"\n");

                    sb.append("學號["+i+"] ="+soapChildsChilds.getProperty(1).toString()+"\n");

                    sb.append("性別["+i+"] = "+soapChildsChilds.getProperty(2).toString()+"\n"+"\n");

            }

                txt1.setText(sb.toString());

            }else{

                txt1.setText("無返回");

            }

        }catch (Exception e) {

            e.printStackTrace();

        }

    }

}

區別就是對於返回值的處理上,使用幾次getPropert()方法,這裏主要看返回值的層次,看下面的結果應該就能明白了,根據括號的層次來進行確定

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章