Android調用WebService

 http://www.xuebuyuan.com/1923390.html

WebService服務端的創建

建立一個WebService項目html

在myeclipse中進行 File-->new-->Web Service Project進入以下界面填寫工程名以後直接完成便可。java

 

接着創建須要的各類類。跟常規建類的方法沒有區別android

項目名稱-->src目錄下右擊-->new-->Classweb

我這裏創建兩個類一個是主要的操做類,一個是模擬的entity類tomcat

主類操做類服務器

Test.java網絡

 

package com.demo.test;

import java.util.ArrayList;
import java.util.List;

import com.demo.test.entity.UserInfo;

public class Test {

	public String getNumString() {
		return "12300000000";
	}

	/**
	 * 獲取用戶信息
	 * @return
	 */
	public List<UserInfo> getUser() {
		List<UserInfo> list = new ArrayList<UserInfo>();
		UserInfo userInfo = new UserInfo();

		userInfo.setId(1);
		userInfo.setUserName("張三");
		userInfo.setPassword("123");
		userInfo.setSex("男");
		userInfo.setAge(19);
		list.add(userInfo);

		userInfo = new UserInfo();
		userInfo.setId(2);
		userInfo.setUserName("李四");
		userInfo.setPassword("456");
		userInfo.setSex("女");
		userInfo.setAge(18);
		list.add(userInfo);

		return list;
	}
	
	/**
	 * 根據ID獲取用戶信息
	 * @return
	 */
	public UserInfo getUserById(int id) {
		UserInfo userInfo = new UserInfo();

		userInfo.setId(id);
		userInfo.setUserName("虛擬用戶:張三");
		userInfo.setPassword("123");
		userInfo.setSex("男");
		userInfo.setAge(19);


		return userInfo;
	}

}

其中定義了三個方法,是爲了進行測試用的,首先第一種方法是單純的返回一個字符串,第二個方法是返回一個List,第三個方法是通過傳入參數來查找用戶。app

上面用到的entity以下eclipse

UserInfo.javaide

 

package com.demo.test.entity;

public class UserInfo {

	private int id = 0;
	private String userName = null;
	private String password = null;
	private int age = 18;
	private String sex = null;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

}

接下來的操做纔是重點

首先創建webservice服務

 

接着選擇new Web Service進入以下界面 而且在strategy中選擇第二個(根據java文件創立webservice)

 

接着進行下一步

在java class中選擇已經寫好的test.java類 而且選中Generate wsdl in project.最後點擊finish

 

到這一步webservice已經開發的差很少了。最後一步 須要添加jar包

右擊項目名-->build path-->Configure Build Path...-->Add Library-->Myeclipse Libraries-->而後選擇關於JAX-WS的兩個包

 

詳細配置以下:

 

在此須要說明一點TestDelegate.java類是自動生成的,其中記錄了不少重要的信息。

如Namespace、URL、portName等等

 

package com.demo.test;

import java.util.ArrayList;
import java.util.List;
import com.demo.test.entity.UserInfo;

@javax.jws.WebService(targetNamespace = "http://test.demo.com/", serviceName = "TestService", portName = "TestPort", wsdlLocation = "WEB-INF/wsdl/TestService.wsdl")
public class TestDelegate {

	com.demo.test.Test test = new com.demo.test.Test();

	public String getNumString() {
		return test.getNumString();
	}

	public List<UserInfo> getUser() {
		return test.getUser();
	}

	public UserInfo getUserById(int id) {
		return test.getUserById(id);
	}

}

 

至此,webService已經開發完畢了 接着將項目部署到tomcat中,而後開啓tomcat 接着訪問

http://localhost:8080/WebServicePro/TestPort?wsdl

若是看到如下界面說明已經WebService已經開發完成了。

 

接着下來是開發Android端

在Android開發的時候這裏須要使用一個jar包

下載該夾包能夠直接登陸http://code.google.com/p/ksoap2-android/,如今該站點已經提供了直接的下載,只要點擊下載連接就能夠下載了;

百度網盤地址:點擊打開連接(ksoap2-android-assembly-3.0.0-jar-with-dependencies.jar)

 

android中經過webservice調用服務器端其實仍是很簡單的,只要循序漸進的按照下面步驟進行便可:

(1)建立HttpTransportSE對象,該對象用於調用WebService操做

HttpTransportSE ht = new HttpTransportSE(SERVICE_URL);

(2)建立SoapSerializationEnvelope對象

		// 使用soap1.1協議建立Envelop對象
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
				SoapEnvelope.VER11);

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

		// 實例化SoapObject對象
		SoapObject object = new SoapObject(SERVICE_NAMESPACE, mathodName);

 

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

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

				// 設置參數
				object.addProperty("id", 1);

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

  的傳出SOAP消息體

 

				// 將SoapObject對象設置爲SoapSerializationEnvelope對象的傳出SOAP消息
				envelope.bodyOut = object;

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

					// 調用webService
					ht.call(null, envelope);

 

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

  調用web service的返回值

				SoapObject result = (SoapObject) envelope.bodyIn;
				String name = result.getProperty(0).toString();

以上步驟參照http://www.cnblogs.com/shenliang123/archive/2012/07/05/2578586.html 能夠去看看

 

下來爲代碼實例

activity_main.xml

 

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/hello"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/hello_world" />

        <EditText
            android:id="@+id/edit1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/hello"
            android:inputType="textMultiLine" />

        <EditText
            android:id="@+id/edit2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/edit1"
            android:inputType="textMultiLine" />

        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/edit2"
            android:layout_below="@+id/edit2"
            android:text="無參數查詢" />

        <Button
            android:id="@+id/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBaseline="@+id/button1"
            android:layout_alignBottom="@+id/button1"
            android:layout_alignRight="@+id/edit2"
            android:text="有參數查詢" />
    </RelativeLayout>

</ScrollView>

 

此代碼中定義了調用了WebService服務端的三個代碼

一、當用戶剛開始進入的時候默認調用返回字符串的方法getNumString(0

二、當用戶點擊無參數查詢的時候調用List<UserInfo> getUser() 方法返回一個List

三、當用戶點擊有參數查詢的時候調用UserInfo getUserById(int id) 方法,傳參查找具體內容

MainActivity.java

 

package com.demo.webserviceclient;

import java.io.IOException;

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

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.os.StrictMode;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

@SuppressLint("NewApi")
public class MainActivity extends Activity {

	// 在webService服務端中能夠找到NAMESPAC的具體內容
	private static final String SERVICE_NAMESPACE = "http://test.demo.com/";
	// URL
	private static final String SERVICE_URL = "http://192.168.1.104:8080/WebServicePro/TestPort?wsdl";

	private EditText edit1 = null;
	private EditText edit2 = null;
	
	private Button btn1 = null;
	private Button btn2 = null;

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

		edit1 = (EditText) findViewById(R.id.edit1);
		edit2 = (EditText) findViewById(R.id.edit2);
		btn1 = (Button) findViewById(R.id.button1);
		btn2 = (Button) findViewById(R.id.button2);
		
		// 若是本系統爲4.0以上(Build.VERSION_CODES.ICE_CREAM_SANDWICH爲android4.0)
		if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
			// 詳見StrictMode文檔
			StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
					.detectDiskReads().detectDiskWrites().detectNetwork()
					.penaltyLog().build());
			StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
					.detectLeakedSqlLiteObjects().detectLeakedClosableObjects()
					.penaltyLog().penaltyDeath().build());
		}

		// 調用的方法
		String mathodName = "getNumString";
		// 建立HttpTransportSE對象
		HttpTransportSE ht = new HttpTransportSE(SERVICE_URL);
		ht.debug = true;

		// 使用soap1.1協議建立Envelop對象
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
				SoapEnvelope.VER11);

		// 實例化SoapObject對象
		SoapObject object = new SoapObject(SERVICE_NAMESPACE, mathodName);

		// 將SoapObject對象設置爲SoapSerializationEnvelope對象的傳出SOAP消息
		envelope.bodyOut = object;

		try {
			// 調用webService
			ht.call(null, envelope);
			System.out.println("envelope.getResponse()---"
					+ envelope.getResponse());
			if (envelope.getResponse() != null) {
				SoapObject result = (SoapObject) envelope.bodyIn;
				String name = result.getProperty(0).toString();
				edit1.setText("返回值爲:" + name);
				
			} else {
				edit1.setText("無返回值");
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (XmlPullParserException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		
		
		btn1.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				
				// 調用的方法
				String mathodName = "getUser";
				// 建立HttpTransportSE對象
				HttpTransportSE ht = new HttpTransportSE(SERVICE_URL);
				ht.debug = true;

				// 使用soap1.1協議建立Envelop對象
				SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
						SoapEnvelope.VER11);

				// 實例化SoapObject對象
				SoapObject object = new SoapObject(SERVICE_NAMESPACE, mathodName);

				// 將SoapObject對象設置爲SoapSerializationEnvelope對象的傳出SOAP消息
				envelope.bodyOut = object;
				
				try {
					// 調用webService
					ht.call(null, envelope);
					edit2.setText("回傳的值 :"+envelope.getResponse());
					if (envelope.getResponse() != null) {
						SoapObject result = (SoapObject) envelope.bodyIn;
						StringBuilder sb = new StringBuilder();
						for (int i = 0; i < result.getPropertyCount(); i++) {
							SoapObject msg = (SoapObject) result.getProperty(i);
							if (msg != null) {
								sb.append("名稱[").append(i).append("]\t\t").append(msg.getProperty(4).toString()).append("\n");
								sb.append("年齡[").append(i).append("]\t\t").append(msg.getProperty(0).toString()).append("\n");
								sb.append("ID[").append(i).append("]\t\t").append(msg.getProperty(1).toString()).append("\n");
								sb.append("密碼[").append(i).append("]\t\t").append(msg.getProperty(2).toString()).append("\n");
								sb.append("性別[").append(i).append("]\t\t").append(msg.getProperty(3).toString()).append("\n").append("\n");
							}
							
							
						} 
						edit1.setText(sb);
					} else {
						edit1.setText("無返回");
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (XmlPullParserException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
		});
		
		
		btn2.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				
				// 調用的方法
				String mathodName = "getUserById";
				// 建立HttpTransportSE對象
				HttpTransportSE ht = new HttpTransportSE(SERVICE_URL);
				ht.debug = true;

				// 使用soap1.1協議建立Envelop對象
				SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
						SoapEnvelope.VER11);

				// 實例化SoapObject對象
				SoapObject object = new SoapObject(SERVICE_NAMESPACE, mathodName);
				
				// 設置參數
				object.addProperty("id", 1);

				// 將SoapObject對象設置爲SoapSerializationEnvelope對象的傳出SOAP消息
				envelope.bodyOut = object;
				
				try {
					// 調用webService
					ht.call(null, envelope);
					edit2.setText("回傳的值 :"+envelope.getResponse());
					if (envelope.getResponse() != null) {
						SoapObject result = (SoapObject) envelope.bodyIn;
						SoapObject msg = (SoapObject) result.getProperty(0);
						StringBuilder sb = new StringBuilder();
						sb.append("名稱\t\t").append(msg.getProperty(4).toString()).append("\n");
						sb.append("年齡\t\t").append(msg.getProperty(0).toString()).append("\n");
						sb.append("I   D\t\t").append(msg.getProperty(1).toString()).append("\n");
						sb.append("密碼\t\t").append(msg.getProperty(2).toString()).append("\n");
						sb.append("性別\t\t").append(msg.getProperty(3).toString()).append("\n").append("\n");
							
							
						edit1.setText(sb);
					} else {
						edit1.setText("無返回");
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (XmlPullParserException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
		});

	}

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

}

最後在AndroidManifest.xml中加入訪問網絡權限

 

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

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.demo.webserviceclient.MainActivity"
            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>

運行結果以下:初始界面

 

當點擊無參數查詢的時候運行結果以下(由於使用了ScrollView,所以能夠上下滾動)

 

當點擊了有參數查詢的時候

 

PS:getPropert的使用次數相當重要,這裏主要看返回值的層次,沒有掌握的時候能夠debug調試跟跟代碼進行增長減。

若是不對會產生java.lang.ClassCastException: org.ksoap2.serialization.SoapPrimitive cannot的錯誤提示。進入debug中調試調試就ok了。

 

 

PPS:以上的代碼其實仍是不健全的,會發現調用service中方法時傳參爲null

由於細心的話就能夠發現,在有參數查詢的時候參數的值並無傳過去,其實就是這句代碼

 

				// 設置參數
				object.addProperty("id", 1);

當將參數名與服務器端保持一致,但不成功

可是當這裏的參數設置爲arg0、arg一、arg2……argn的時候居然是正確的。

正確代碼以下:

// 設置參數 object.addProperty("arg0", 1);

截圖在這裏就不截了,內容就是上面圖中的id=0顯示爲id=1

相關文章
相關標籤/搜索