建立一個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開發的時候這裏須要使用一個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了。
由於細心的話就能夠發現,在有參數查詢的時候參數的值並無傳過去,其實就是這句代碼
// 設置參數 object.addProperty("id", 1);
當將參數名與服務器端保持一致,但不成功
可是當這裏的參數設置爲arg0、arg一、arg2……argn的時候居然是正確的。
正確代碼以下:
// 設置參數 object.addProperty("arg0", 1);
截圖在這裏就不截了,內容就是上面圖中的id=0顯示爲id=1