昨天有人問我Android怎麼鏈接mysql數據庫,和對數據庫的操做呀,我想把,給他說說json通訊,但是他並不知道怎麼弄,哎算了吧,直接叫他用ksoap吧,給他說了大半天,好多零碎的知識,看來仍是有必要把這些東西整合起來,一方面本身有時候也看,另外一方面固然是能幫助沒有作個的小夥伴,其實東西不是不少,就是講的有點詳細,不怕多,就怕不仔細,
WebServices簡介
Web services是一種部署在Web上的對象或者組件,可以經過Internet進行調用的應用程序。Web services 創建在以XML爲主的開放的web規範技術基礎上,其業務邏輯對調用者來講是透明的。java
Webservices調用須要注意的問題(附案例)
接下來咱們結合一個案例來理解整個調用過程,針對當時開發時遇到的問題,進行詳細說明。
附:表達能力有限,有不少東西講的不是很清楚,請結合附帶案例看此文檔,但願能幫到你
準備工做
相關jar包導入
新建android項目,將ksoap2-android-assembly-3.0.0-jar-with-dependencies.jar放在android項目的lib目錄下,檢查jar包是否以下圖所示:
相關權限添加
既然是訪問網絡操做,就須要添加訪問網絡的權限:
對AndroidManifest.xml文件進行修改,添加網絡權限
,
調用webService服務步驟
第一步,指定WebServices的命名空間和調用的方法名
SoapObjectrpc = new SoapObject(NameSpace,methodName);
第二步,設置須要調用的webServices接口須要傳入的參數
rpc.addProperty(proPertyName,proPertyValue);
第三步,生成調用WebServices方法的SOAP請求信息,並制定SOAP的版本
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER10);
envelope.bodyOUt = rpc;
第四步,生成調用WebServices方法的HttpTransportSE實體對象
HttpTransportSE transport = new HttpTransportSE(ServiceURL);
第五步,調用call方法請求服務
Transport.call(soapAction,envelope);
第六步,獲取服務端返回的數據
SoapObject object = (SoapObject)envelope.bodyIn;
第七步,解析返回的soapObject並獲取須要的數據結果
String result = object.getProPerty(0).toString();
對調用過程的分析
注意1:第一步、第四步、第五步中,涉及到調用WebServices以前須要弄清楚」NameSpace」、」methodName」、」serviceURL」、」soapAction」。這些值須要從wsdl文檔中尋找,若是想對wsdl文檔深刻學習,請參考wsdl學習文檔,本文檔只說明如何從wsdl文檔中找到相應的值。
將服務端提供的url地址瀏覽器地址欄能夠看到以下界面:
經過連接訪問wsdl文檔,能夠看到當前wsdl文檔應用的所得有命名空間,內容界面以下:
在此文檔中,咱們也能夠找到咱們須要的四個重要的屬性值:
命名空間:找到wsdl:definitions節點,即wsdl的根節點,找到屬性targetNamespace的值,即爲咱們所需的命名空間nameSpace的值,如圖:
方法名和SoapAction:找到wsdl:operation節點,其屬性name的值即爲咱們所需的方法名methodName的值,其子節點soap:operation的屬性SoapAction的值即爲當前咱們所需方法所對應的soapAction的值,如圖:
至此,調用webService服務所需的最基本的四個屬性值獲取完成。但調用的過程當中必定要保證methodName與soapAction的一一對應關係。
注意2:第二步中,涉及到設置參數。經過wsdl文件中wsdl:types節點的子節點xsd:import
經過第一個URL獲取到當前服務的全部方法、每一個方法的全部參數及參數類型
經過第二個URL獲取到當前服務全部能直接傳遞的數據類型,即基本數據類型
經過第三個URL獲取到當前服務全部自定義類型的參數、參數的全部屬性及屬性類型
經過第一個URL訪問到以下界面:
針對參數類型,如何判斷參數是否是自定義參數類型呢?能夠經過第二個URL跳轉查看服務描述的全部基本數據類型,以下圖:
若沒有,經過第三個URL跳轉查看服務描述的全部自定義類型,一一對應的關係,若是沒有在當前連接裏找到你所要了解的數據類型,那麼這種數據類型即爲複雜類型,或稱自定義類型。須要對自定義類型的屬性加以進一步瞭解,以下圖:
若沒有,能夠詢問服務端負責人員
自定義數據類型參數問題
針對這種自定義類型的參數,經過第二步中設置參數是達不到咱們想要的效果的,服務端返回的信息爲」服務器內部錯誤」等。那麼這種狀況咱們該怎麼解決呢?
下面拿上述TransferParams講解一下:
第一步、在本地新建TransferParams.java文件,實現KvmSerializable序列化接口。
第二步、將上圖中TransferParams參數包含的全部屬性按順序聲明,注意:必定要按順序
第三步、實現getProperty(int arg0)、getPropertyCount()、getPropertyInfo(int arg0,Hashtable arg1,PropertyInfo arg2)、setProperty(int arg0,Object arg1)方法。
getProperty(int arg0) 經過索引獲取指定屬性
getPropertyCount() 獲取屬性集合的大小
getPropertyInfo(int arg0,Hashtable arg1,PropertyInfo arg2)
獲取指定索引的屬性的名稱和類型,注意:方法中第一件事是爲參數設置命名空間
setProperty(int arg0,Object arg1) 爲指定的屬性賦值
第四步、在調用過程當中,添加本地數據類型與服務端數據類型的映射,經過addMapping()方法在調用webService服務的HttpTransportSE對象調用call()方法以前。
addMapping()方法有三個參數,分別是服務端的引用url、參數名和本地對應的類型。代碼以下:envelope.addMapping(soapMapping, 「TransferParams」, TransferParams.class);
三個參數可經過自定義參數描述文件中xs:schema節點的targetNamespace屬性值、xs:complexType節點的name屬性值獲取到SoapMapping和TransferParams兩個值。
這樣自定義類型的參數的問題也差很少能解決了。
帶有自定義類型屬性的自定義類型參數
可是此刻就又有問題了,你應該發現了此時自定義類型參數的全部屬性都是基本數據類型,那若是此參數的某個屬性也是自定義類型的,該怎麼解決呢?解決方法與上述自定義類型的解決方法類似,就是新建java文件實現kvmSerializable序列化接口來描述自定義類型的屬性,而後以普通屬性的形式在自定義類型參數中聲明。
自定義類型參數集合
到這裏,自定義類型的參數問題已經解決了一半,剩下的一半是自定義類型參數集合。若是擁有自定義類型屬性的自定義參數你理解了,那麼這剩下的一半自定義類型參數集合就很容易了。這裏你能夠把集合想象成一個有且只有一個屬性的參數,而此屬性也爲自定類型的。只是不一樣的是你在新建集合的java文件時,須要繼承Vector,這裏的E指的是集合中包含的參數類型。固然參數類型的映射仍須要添加。mysql
最後,針對上面的資源用一個完整的案例幫助你們分析一下,因此請容我再囉嗦一遍
準備工做
服務地址 http://10.0.1.223:9100/KdtService/
Ksoap2-android.Jar包 下載地址:http://pan.baidu.com/s/1CE754
一、 新建android項目,導入jar包,添加權限
二、 修改activity_main.xml文件,添加三個按鈕分別用於測試無參(基本數據類型)webServices服務調用、自定義參數webServices服務調用、自定義參數集合webServices服務調用和一個用於顯示結果的顯示框,代碼以下:
package com.example.webservicetest;android
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;web
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;sql
public class WebServiceOp {
//命名空間
private static final String NAME_SPACE = "http://tempuri.org/";
//服務地址
private static final String URL = "http://10.0.1.223:9100/KdtService/basic";
//操做方法的名稱
private static String methodName = "";
private static String soapMapping = "http://schemas.datacontract.org/2004/07/WebServiceManager";
private static LinkedHashMap<String,Object>paramMap;
private static TransferParamstran;
private static int flag = 1;
/**
* 公用方法
* @parammethodname方法名稱
* @paramparamMap 參數集合
* @return
* @throws IOException
*/
public static SoapObjectLoadResult(String methodname,Map<String,Object>paramMap) throws IOException{
//建立soap對象,傳入所需調用的webService的命名空間和webService方法名
SoapObjectsoapObject = new SoapObject(NAME_SPACE, methodname);
//建立SoapSerializationEnvelope對象,傳入所需版本
SoapSerializationEnvelope envelope
= new SoapSerializationEnvelope(SoapEnvelope.VER11);
//建立HttpTransportSE對象,該對象用於調用webService操做
HttpTransportSE trans = new HttpTransportSE(URL,20000);
//判斷參數集合是否爲空
if(paramMap != null)
{
//將map中的參數放入迭代器中
Iterator<Entry<String, Object>>iter = paramMap.entrySet().iterator();
//遍歷迭代器,爲soap對象設置參數
while(iter.hasNext()){
Map.Entry<String, Object> me = iter.next();
soapObject.addProperty(me.getKey(),"".equals(me.getValue())?null:me.getValue());
}
//服務器端自定義類型的映射
switch(flag)
{
case 0:
break;
case 1:
envelope.addMapping(soapMapping, "TransferParams", TransferParams.class);
break;
case 2:
envelope.addMapping(soapMapping, "TransferParams", TransferParams.class);
envelope.addMapping(soapMapping, "ParamEnt", ParamEnt.class);
envelope.addMapping(soapMapping, "ArrayOfParamEnt", ArrayOfPEnt.class);
break;
case 3:
envelope.addMapping(soapMapping, "TransferParams", TransferParams.class);
envelope.addMapping(soapMapping, "ScanData", ScanData.class);
envelope.addMapping(soapMapping, "ArrayOfScanData", ArrayOfScanData.class);
break;數據庫
default:
break;
}json
}
//建立的SoapObject對象設爲SoapSerializationEnvelope的傳出SOAP消息體
envelope.bodyOut = soapObject;
envelope.setOutputSoapObject(soapObject);
//設置兼容.net服務器端
envelope.dotNet = true;
//使用調試功能
trans.debug = true; 數組
try {
//調用操做對象call方法,將SoapSerializationEnvelope做爲參數調用遠程webService
trans.call(NAME_SPACE + "IKdtService/" + methodname, envelope);
System.out.println(trans.requestDump);
//調用完成,訪問SoapSerializationEnvelope對象的bodyIn屬性,該屬性返回一個SoapObject對象,該對象表明webService的返回信息
SoapObject result = (SoapObject) envelope.bodyIn;
//打印Log日誌信息
return result;
} catch (XmlPullParserException e) {
e.printStackTrace();
return null;
}
}
//無參調用
public static SoapObjectserverTime() throws IOException
{
methodName = "ServerTime";
flag = 0;
return LoadResult(methodName, null);
}
//自定義類型參數調用
public static SoapObject register() throws IOException
{ //設置須要調用的服務器接口方法的名稱
methodName = "Register";瀏覽器
tran = new TransferParams();
tran.setCompress(true);
tran.setDBType(0);
tran.setDefaultLogic(true);
tran.setEnterpriseID("Thinta");
tran.setFileType(0);
tran.setPDAID("1000000");
tran.setStationID("900001");
//將自定義類型以參數形式放入map集合中
paramMap = new LinkedHashMap<String, Object>();
paramMap.put("param", tran);
flag = 1;
return LoadResult(methodName, paramMap);
}
//含有自定義類型參數集合的調用
public static SoapObjectdownLoad() throws IOException
{
methodName = "Download";緩存
tran = new TransferParams();
tran.setCompress(true);
tran.setDBType(0);
tran.setDefaultLogic(true);
tran.setEnterpriseID("Thinta");
tran.setFileType(0);
tran.setPDAID("1000000");
tran.setStationID("900001");
ParamEnt p1= new ParamEnt();
p1.setTableName("SiteInfo");
ParamEnt p2 = new ParamEnt();
p2.setTableName("Employee");
ArrayOfPEntaope = new ArrayOfPEnt();
aope.add(p1);
aope.add(p2);
paramMap = new LinkedHashMap<String, Object>();
paramMap.put("param", tran);
paramMap.put("list", aope);
flag = 2;
return LoadResult(methodName, paramMap);
}
}
1
對於這個類,須要囉嗦幾句。
主要方法是LoadResult(String methodName, Map
package com.example.webservicetest;
import java.util.Hashtable;
import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.PropertyInfo;
public class TransferParams implements KvmSerializable{
private boolean Compress;
private intDBType;
private booleanDefaultLogic;
private String EnterpriseID;
private intFileType;
private String MD5;
private String PDAID;
private String StationID;
private String Version;
@Override
public Object getProperty(int arg0) {
switch (arg0) {
case 0:
return Compress;
case 1:
return DBType;
case 2:
return DefaultLogic;
case 3:
return EnterpriseID;
case 4:
return FileType;
case 5:
return MD5;
case 6:
return PDAID;
case 7:
return StationID;
case 8:
return Version;
default:
return null;
}
}
@Override
public intgetPropertyCount() {
return 9;//參數的個數
}
@Override
public void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo arg2) {
//這個很重要
arg2.namespace="http://schemas.datacontract.org/2004/07/WebServiceManager"; switch (arg0) {
case 0:
arg2.type=PropertyInfo.BOOLEAN_CLASS;
arg2.name="Compress";
break;
case 1:
arg2.type=PropertyInfo.INTEGER_CLASS;
arg2.name="DBType";
break;
case 2:
arg2.type=PropertyInfo.BOOLEAN_CLASS;
arg2.name="DefaultLogic";
break;
case 3:
arg2.type=PropertyInfo.STRING_CLASS;
arg2.name="EnterpriseID";
break;
case 4:
arg2.type=PropertyInfo.INTEGER_CLASS;
arg2.name="FileType";
break;
case 5:
arg2.type=PropertyInfo.STRING_CLASS;
arg2.name="MD5";
break;
case 6:
arg2.type=PropertyInfo.STRING_CLASS;
arg2.name="PDAID";
break;
case 7:
arg2.type=PropertyInfo.STRING_CLASS;
arg2.name="StationID";
break;
case 8:
arg2.type=PropertyInfo.STRING_CLASS;
arg2.name="Version";
break;
default:
break;
}
}
@Override
public void setProperty(int arg0, Object arg1) {
switch (arg0) {
case 0:
Compress = Boolean.getBoolean(arg1.toString());
break;
case 1:
DBType = Integer.valueOf(arg1.toString());
break;
case 2:
DefaultLogic = Boolean.getBoolean(arg1.toString());
break;
case 3:
EnterpriseID = arg1.toString();
break;
case 4:
FileType = Integer.valueOf(arg1.toString());
break;
case 5:
MD5 = arg1.toString();
break;
case 6:
PDAID = arg1.toString();
break;
case 7:
StationID = arg1.toString();
break;
case 8:
Version = arg1.toString();
break;
default:
break;
}
}
public booleanisCompress() {
return Compress;
}
public void setCompress(boolean compress) {
Compress = compress;
}
public intgetDBType() {
return DBType;
}
public void setDBType(intdBType) {
DBType = dBType;
}
public booleanisDefaultLogic() {
return DefaultLogic;
}
public void setDefaultLogic(booleandefaultLogic) {
DefaultLogic = defaultLogic;
}
public String getEnterpriseID() {
return EnterpriseID;
}
public void setEnterpriseID(String enterpriseID) {
EnterpriseID = enterpriseID;
}
public intgetFileType() {
return FileType;
}
public void setFileType(intfileType) {
FileType = fileType;
}
public String getMD5() {
return MD5;
}
public void setMD5(String mD5) {
MD5 = mD5;
}
public String getPDAID() {
return PDAID;
}
public void setPDAID(String pDAID) {
PDAID = pDAID;
}
public String getStationID() {
return StationID;
}
public void setStationID(String stationID) {
StationID = stationID;
}
public String getVersion() {
return Version;
}
public void setVersion(String version) {
Version = version;
}
}
1
201
202
此文件中除了屬性的名稱須要同wsdl文件中的一致,getProperty()、getPropertyInfo()、setProperty()方法中屬性的順序須要注意意外,特別須要注意就是上邊紅色代碼部分,一個是getCount()方法的返回值,一個是getPropertyInfo()方法第三個參數的命名空間的設置。返回值是隨着屬性的改變而改變的,這點必定要注意,若是當前返回值小於屬性的總數,調用的過程當中可能會出現數組越界的異常;命名空間也是與wsdl文件中的值對應的,若是命名空間匹配出錯,會影響服務器端的處理及返回值,拿本例來說,若是把命名空間賦值的代碼註釋掉,調用服務返回的結果是ERROR,而命名空間賦值匹配正確的狀況下,調用服務返回的結果則是PAD IS REGISTEDS,因此必定要注意命名空間的賦值。除了命名空間的匹配外,咱們還須要進行服務端與客戶端對自定義類型的映射,就是那段addMapping添加映射的代碼,第一個參數是服務端自定義類型參數所處的命名空間對應的引用,第二個參數是此類型參數在服務端的參數名稱,第三個參數是客戶端(即本地)該自定義類型的參數所對應的類型。
包括自定義類型、類型映射工做作完並都保證正確以後,再進行服務調用操做,應該就不會出現錯誤了。
自定義類型參數集合(downLoad)在此處表明含有自定義屬性的自定義參數和自定義參數集合的調用服務操做,這裏的參數爲ArrayOfPEnt類型,由於它表明的是ParamEnt類型的集合,針對這種自定義類型,咱們一樣須要映射,既然要映射,就須要服務器端和客戶端的各自的類型,而此時只有服務器端對這個類型進行了定義,客戶端並無對這個類型進行定義,因此接下來的第一件事就是定義ArrayOfPEnt類型。具體做法以下:
五、 新建ParamEnt.java文件,作法同第四步相同,這裏重點說一下ArrayOfPEnt.java文件,實現KvmSerializable接口並繼承Vector容器類,以便起到集合的做用。代碼以下:
package com.example.webservicetest;
import java.util.Hashtable;
import java.util.Vector;
import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.PropertyInfo;
public class ArrayOfPEnt extends Vector<ParamEnt>
implements
KvmSerializable
{
@Override
public Object getProperty(int arg0)
{
return this.get(arg0);
}
@Override
public intgetPropertyCount()
{
return this.size();
}
@Override
public void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo arg2)
{
// arg2.namespace = "http://schemas.datacontract.org/2004/07/WebServiceManager";
arg2.name = "ParamEnt";
arg2.type = ParamEnt.class;
}
@Override
public void setProperty(int arg0, Object arg1)
{
this.add((ParamEnt) arg1);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
須要注意的地方同第四步,此處再也不贅述。
六、 編寫MainActivity.java文件,以下:
package com.example.webservicetest;
import java.io.IOException;
import org.ksoap2.serialization.SoapObject;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.TextureView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener{
Button b1,b2,b3;
TextView t;
private SoapObjectsoapObject = new SoapObject();
private String resultStr = "";
private Handler mHandler = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
t = (TextView) findViewById(R.id.textView);
b1 = (Button) findViewById(R.id.simple);
b2 = (Button) findViewById(R.id.simplecom);
b3 = (Button) findViewById(R.id.comlist);
b1.setOnClickListener(this);
b2.setOnClickListener(this);
b3.setOnClickListener(this);
mHandler = new Handler()
{
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0x11:
t.setText(resultStr);
break;
case 0x12:
t.setText(resultStr);
break;
case 0x13:
t.setText(resultStr);
break;
default:
break;
}
}
};
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.simple:
new Thread(){
public void run() {
try {
soapObject = WebServiceOp.serverTime();
resultStr = "請求無參的服務調用-->結果爲:" + soapObject.toString();
Message msg = new Message();
msg.what = 0x11;
mHandler.sendMessage(msg);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
}.start();
break;
case R.id.simplecom:
new Thread()
{
public void run() {
try {
soapObject = WebServiceOp.register();
resultStr = "請求自定義參數的服務調用-->結果爲:" + soapObject.toString();
Message msg = new Message();
msg.what = 0x12;
mHandler.sendMessage(msg);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
}.start();
break;
case R.id.comlist:
new Thread()
{
public void run() {
try {
soapObject = WebServiceOp.downLoad();
resultStr = "請求自定義參數集合的服務調用-->結果爲:" + soapObject.toString();
Message msg = new Message();
msg.what = 0x13;
mHandler.sendMessage(msg);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
}.start();
break;
default:
break;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
上面的方法你如果以爲太雜太亂的話,我有寫了一個高度集中的方法,面對任何參數任何類型的,簡單數據類型,自定義對象。。。看看吧
package com.agbc.webservice;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.SoapFault;
import org.ksoap2.serialization.MarshalBase64;
import org.ksoap2.serialization.MarshalDate;
import org.ksoap2.serialization.MarshalFloat;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;
import sun.management.resources.agent;
import com.agbc.Api.AgbcApi;
import com.agbc.entity.TUser;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
import android.support.v4.util.LruCache;
import android.util.Log;
/**
* 請求webservice封裝類
* 2016/4/10 進行優化,添加三級緩存技術
* @author double 江
*
*/
public class WebServiceBase {
public static final int SUCCSEE = 0;
public static final int FAIL = 1;
private SoapObject request;
public WebServiceBase() {
}
public WebServiceBase(Context context,Handler handler){
Executors.newFixedThreadPool(5);
}
/**
* 經過傳遞簡單數據類型參數,
* 服務端方法名稱獲取範圍webservice的數據,
* 倒數第二個參數是服務端的方法名,必須與服務端一致。
* 最後一個參數是服務端url,
*
* @param arg 參數列表Object類型的
* @return 返回SoapObject類型的原始數據
*/
public SoapObject getBaseSimpleData(Object...arg){
final String methodName=arg[(arg.length-2)].toString();
final String soapAction=AgbcApi.NAMESPACE+methodName;
request = new SoapObject(AgbcApi.NAMESPACE, methodName);
for (int i = 0; i < arg.length-2; i++) {
request.addProperty("arg"+i, arg[i]);
Log.i("arg"+i, arg[i].toString());
}
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
(new MarshalBase64()).register(envelope);
envelope.bodyOut = request;
envelope.dotNet=false;
envelope.setOutputSoapObject(request);
HttpTransportSE ht = new HttpTransportSE(arg[arg.length-1].toString(),10000);
ht.debug=true;
try {
ht.call(soapAction, envelope);
if(envelope.bodyIn instanceof SoapFault){
String str = ((SoapFault) envelope.bodyIn).faultstring;//返回的是空節點
Log.i("返回錯誤的數據", str);
}
else {
request=(SoapObject) envelope.bodyIn;
Log.i("得到原始數據", request.toString());
}
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
return request;
};
/**
* 經過傳遞簡單數據類型參數,
* 服務端方法名稱獲取範圍webservice的數據,
* 倒數第三個位回調標記 int類型的
* 倒數第二個參數是服務端的方法名,必須與服務端一致。
* 最後一個參數是服務端url,
* @param arg 參數列表Object類型的
*
*/
public SoapObject getBaseSimpleDataByNamespace(Object...arg){
final String methodName=arg[(arg.length-2)].toString();
final String soapAction=AgbcApi.NAMESPACETWO+methodName;
request = new SoapObject(AgbcApi.NAMESPACETWO, methodName);
for (int i = 0; i < arg.length-2; i++) {
request.addProperty("arg"+i, arg[i]);
Log.i("arg"+i, arg[i].toString());
}
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
(new MarshalBase64()).register(envelope);
envelope.bodyOut = request;
envelope.dotNet=false;
envelope.setOutputSoapObject(request);
HttpTransportSE ht = new HttpTransportSE(arg[arg.length-1].toString(),10000);
ht.debug=true;
try {
ht.call(soapAction, envelope);
if(envelope.bodyIn instanceof SoapFault){
String str = ((SoapFault) envelope.bodyIn).faultstring;//返回的是空節點
Log.i("返回錯誤的數據", str);
}
else {
request=(SoapObject) envelope.bodyIn;
Log.i("得到原始數據", request.toString());
}
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
return request;
};
// public void getBaseSimpleData1(final Object...arg){
// executorService.execute(new Runnable() {
// @Override
// public void run() {
// final String methodName=arg[(arg.length-2)].toString();
// final String soapAction=AgbcApi.NAMESPACE+methodName;
// request = new SoapObject(AgbcApi.NAMESPACE, methodName);
// for (int i = 0; i < arg.length-3; i++) {
// request.addProperty("arg"+i, arg[i]);
// Log.i("arg"+i, arg[i].toString());
// }
// SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
// (new MarshalBase64()).register(envelope);
// envelope.bodyOut = request;
// envelope.dotNet=false;
// envelope.setOutputSoapObject(request);
// HttpTransportSE ht = new HttpTransportSE(arg[arg.length-1].toString(),10000);
// ht.debug=true;
// try {
// ht.call(soapAction, envelope);
// if(envelope.bodyIn instanceof SoapFault){
// String str = ((SoapFault) envelope.bodyIn).faultstring;//返回的是空節點
// Log.i("返回錯誤的數據", str);
// Message message=Message.obtain();
// message.what=FAIL;
// handler.sendMessage(message);
// }
// else {
// request=(SoapObject) envelope.bodyIn;
// Log.i("得到原始數據", request.toString());
// message=Message.obtain();
// message.obj=request;
// message.what=(int) arg[arg.length-3];
// handler.sendMessage(message);
//
// }
// } catch (IOException e) {
// e.printStackTrace();
// } catch (XmlPullParserException e) {
// e.printStackTrace();
// }
// }
// });
// };
/**
* 傳遞自定義數據類型對象(序列化後)。
* 1,自定義類對象,
* 2,方法名稱,與服務端一直
* 3,請求的的service
* @return
*/
public SoapObject getBaseComplexData(Object ...arg){
String methodName = arg[arg.length-2].toString().trim();//請求方法名
Log.i("方法名稱", arg[arg.length-2].toString());
String soapAction = arg[(arg.length-1)].toString()+methodName;
Log.i("參數", arg[(arg.length-1)].toString());
// 創建webservice鏈接對象
HttpTransportSE transport = new HttpTransportSE(arg[(arg.length-1)].toString(),10000);//10秒超時
transport.debug = true;// 是不是調試模式
// 設置鏈接參數
SoapObject soapObject = new SoapObject(AgbcApi.NAMESPACE, methodName);
PropertyInfo objekt = new PropertyInfo();
objekt.setName("arg0");
objekt.setValue(arg[0]);
objekt.setType(arg[0].getClass());
soapObject.addProperty(objekt);
// 設置返回參數
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);// soap協議版本必須用SoapEnvelope.VER11(Soap
envelope.dotNet = false;// 注意:這個屬性是對dotnetwebservice協議的支持,若是dotnet的webservice
envelope.bodyOut = transport;
Log.i("請求參數", soapObject.toString());
envelope.setOutputSoapObject(soapObject);// 設置請求參數
new MarshalDate().register(envelope);
envelope.addMapping(AgbcApi.NAMESPACE, methodName,arg[0].getClass());// 傳對象時必須,參數namespace是webservice中指定的,
(new MarshalBase64()).register(envelope);
new MarshalFloat().register(envelope);
try {
transport.call(soapAction, envelope);
if(envelope.bodyIn instanceof SoapFault){
String str = ((SoapFault) envelope.bodyIn).faultstring;
Log.i("錯誤信息", str);
}
else {
request=(SoapObject) envelope.bodyIn;
Object obj = envelope.getResponse();// 直接將返回值強制轉換爲已知對象
Log.i("返回的原始數據obj", obj.toString());
Log.i("返回的原始數據request", request.toString());
return request;
}
}
catch (IOException e) {
e.printStackTrace();
}
catch (XmlPullParserException e) {
e.printStackTrace();
}
catch (Exception ex) {
ex.printStackTrace();
}
// 解析返回的結果
return null;
};
/**
* 傳遞自定義數據類型對象(序列化後)。
* 1,自定義類對象,
* 2,方法名稱,與服務端一直
* 3,請求的的service
* @return
*/
public SoapObject getBaseComplexDataNamespace(Object ...arg){
String methodName = arg[arg.length-2].toString().trim();//請求方法名
Log.i("方法名稱", arg[arg.length-2].toString());
String soapAction = arg[(arg.length-1)].toString()+methodName;
Log.i("參數", arg[(arg.length-1)].toString());
// 創建webservice鏈接對象
HttpTransportSE transport = new HttpTransportSE(arg[(arg.length-1)].toString(),10000);//10秒超時
transport.debug = true;// 是不是調試模式
// 設置鏈接參數
SoapObject soapObject = new SoapObject(AgbcApi.NAMESPACETWO, methodName);
//soapObject.addProperty("", String.valueOf(1));
PropertyInfo objekt = new PropertyInfo();
objekt.setName("arg0");
objekt.setValue(arg[0]);
Log.i("類", arg[0].toString());
objekt.setType(TUser.class);
soapObject.addProperty(objekt);
// 設置返回參數
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);// soap協議版本必須用SoapEnvelope.VER11(Soap
envelope.implicitTypes=true;
envelope.dotNet = false;// 注意:這個屬性是對dotnetwebservice協議的支持,若是dotnet的webservice
//envelope.implicitTypes = true;
envelope.bodyOut = transport;
Log.i("請求參數", soapObject.toString());
envelope.setOutputSoapObject(soapObject);// 設置請求參數
new MarshalDate().register(envelope);
envelope.addMapping(AgbcApi.NAMESPACETWO, methodName, TUser.class);// 傳對象時必須,參數namespace是webservice中指定的,
(new MarshalBase64()).register(envelope);
new MarshalFloat().register(envelope);
try {
transport.call(soapAction, envelope);
if(envelope.bodyIn instanceof SoapFault){
String str = ((SoapFault) envelope.bodyIn).faultstring;
Log.i("錯誤信息", str);
}
else {
request=(SoapObject) envelope.bodyIn;
Object obj = envelope.getResponse();// 直接將返回值強制轉換爲已知對象
Log.i("返回的原始數據obj", obj.toString());
Log.i("返回的原始數據request", request.toString());
return request;
}
}
catch (IOException e) {
e.printStackTrace();
}
catch (XmlPullParserException e) {
e.printStackTrace();
}
catch (Exception ex) {
ex.printStackTrace();
}
// 解析返回的結果
return null;
};}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313思來想去我仍是以爲應該把這個在Activity中訪問網絡的問題囉嗦一下,因爲android 4.0以上版本系統不支持主線程存在耗時操做(包括訪問網絡和大數據計算等),因此須要經過一個線程來處理,如上述代碼中的紅色標註部分。解決方案有不少種,最經常使用的爲handler+thread、AsyncTask兩種方式,在此再也不贅述,個人下一篇博客吧 至此,整個項目差很少完成了,部署,測試一下。對此,你要是在不會用webservice。我就無法了。。。。。--------------------- 做者:twjitm 來源:CSDN 原文:https://blog.csdn.net/baidu_23086307/article/details/51296371 版權聲明:本文爲博主原創文章,轉載請附上博文連接!