经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » Android » 查看文章
Android 基于ksoap2的webservice请求的学习
来源:cnblogs  作者:汪菜菜  时间:2019/11/13 8:40:21  对本文有异议

 【学习阶段】

  • WebService网络请求?

    其实我也是第一次遇到,之所以有这个需要是因为一些与 ERP 相关的业务,需要用到这样的一个请求方式。

  • 开始学习WebService 

  ①当然是百度搜索,这里找了一个学习的博客  https://blog.csdn.net/swjtugiser/article/details/76840353

   使用 ksoap2 框架请求 ,jar 包下载地址   http://simpligility.github.io/ksoap2-android/getting-started.html  ,放在Project 模式的  libs 目录下。

           根据以上地址进行学习。

 

  ②在开发的过程中我们频繁的用到 网络请求,所以我们最好能封装成像okhttp一样的类。 

  1. 1 package com.example.aust_app;
  2. 2
  3. 3
  4. 4 /*Created by wqy on 2019/11/8.*/
  5. 5
  6. 6 import android.content.Context;
  7. 7 import android.os.AsyncTask;
  8. 8
  9. 9 import org.ksoap2.SoapEnvelope;
  10. 10 import org.ksoap2.serialization.SoapObject;
  11. 11 import org.ksoap2.serialization.SoapSerializationEnvelope;
  12. 12 import org.ksoap2.transport.HttpTransportSE;
  13. 13
  14. 14 public class WebRequest {
  15. 15
  16. 16 private String SOAP_ACTION="http://WebXml.com.cn/getRegionProvince"; //可以设置一些默认值
  17. 17 private String NAMESPACE="http://WebXml.com.cn/";
  18. 18 private String METHOD_NAME="getRegionProvince";
  19. 19 private String URL="http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?WSDL";
  20. 20
  21. 21 WebRequest request = null;
  22. 22 Context context = null;
  23. 23
  24. 24
  25. 25 public WebRequest(Context context) {
  26. 26 this.context = context;
  27. 27 }
  28. 28
  29. 29 public static WebRequest init(Context context){
  30. 30 return new WebRequest(context);
  31. 31 }
  32. 32
  33. 33 public String getSOAP_ACTION() {
  34. 34 return SOAP_ACTION;
  35. 35 }
  36. 36
  37. 37 public WebRequest setSOAP_ACTION(String SOAP_ACTION) {
  38. 38 this.SOAP_ACTION = SOAP_ACTION;
  39. 39 return this;
  40. 40 }
  41. 41
  42. 42 public String getNAMESPACE() {
  43. 43 return NAMESPACE;
  44. 44 }
  45. 45
  46. 46 public WebRequest setNAMESPACE(String NAMESPACE) {
  47. 47 this.NAMESPACE = NAMESPACE;
  48. 48 return this;
  49. 49 }
  50. 50
  51. 51 public String getMETHOD_NAME() {
  52. 52 return METHOD_NAME;
  53. 53 }
  54. 54
  55. 55 public WebRequest setMETHOD_NAME(String METHOD_NAME) {
  56. 56 this.METHOD_NAME = METHOD_NAME;
  57. 57 return this;
  58. 58 }
  59. 59
  60. 60 public String getURL() {
  61. 61 return URL;
  62. 62 }
  63. 63
  64. 64 public WebRequest setURL(String URL) {
  65. 65 this.URL = URL;
  66. 66 return this;
  67. 67 }
  68. 68
  69. 69 private SoapObject getInformation(){
  70. 70 SoapObject request=new SoapObject(NAMESPACE,METHOD_NAME);
  71. 71
  72. 72 SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
  73. 73 envelope.setOutputSoapObject(request);
  74. 74 try{
  75. 75 HttpTransportSE transportSE=new HttpTransportSE(URL);
  76. 76 transportSE.call(SOAP_ACTION,envelope);
  77. 77 SoapObject result=(SoapObject)envelope.bodyIn; //获取到返回的结果,并强制转换成SoapObject对象
  78. 78 SoapObject test = (SoapObject)result.getProperty(0); //该对象中还嵌套了一个SoapObject对象,需要使用getProperty(0)把这个对象提取出来
  79. 79 return test;
  80. 80 }catch (Exception e){
  81. 81 e.printStackTrace();
  82. 82 }
  83. 83 return null;
  84. 84 }
  85. 85
  86. 86 SoapObject result; //在子线程中请求webservice
  87. 87 class DownloadTask extends AsyncTask<Void,Integer,Boolean> {
  88. 88
  89. 89 @Override
  90. 90 protected Boolean doInBackground(Void... voids) {
  91. 91 result = getInformation();
  92. 92 return null;
  93. 93 }
  94. 94
  95. 95 @Override
  96. 96 protected void onPostExecute(Boolean aBoolean) {
  97. 97 StringBuilder builder = new StringBuilder();
  98. 98 //解析返回的数据
  99. 99 for(int i=0;i<result.getPropertyCount();i++){
  100. 100 builder.append(result.getProperty(i));
  101. 101 }
  102. 102 if (postExecute!=null){
  103. 103 postExecute.getResult(builder.toString());
  104. 104 }
  105. 105 }
  106. 106 }
  107. 107
  108. 108 public void execute(){
  109. 109 new DownloadTask().execute();
  110. 110 }
  111. 111
  112. 112 PostExecuteListener postExecute;
  113. 113 interface PostExecuteListener{
  114. 114 void getResult(String result);
  115. 115 }
  116. 116
  117. 117 public PostExecuteListener getPostExecute() {
  118. 118 return postExecute;
  119. 119 }
  120. 120
  121. 121 public WebRequest setPostExecuteListener(PostExecuteListener postExecute) {
  122. 122 this.postExecute = postExecute;
  123. 123 return this;
  124. 124 }
  125. 125 }

 

  ③在Activity中使用这样的类

  1. WebRequest.init(this).setURL("url").setNAMESPACE("namespace").setMETHOD_NAME("methodName")
  2. .setSOAP_ACTION("soapAction").setPostExecuteListener(new WebRequest.PostExecuteListener() {
  3. @Override
  4. public void getResult(String result) {
  5. Toast.makeText(Main2Activity.this, ""+result, Toast.LENGTH_SHORT).show();
  6. }
  7. }).execute();

 

 【开发阶段】

  以上是学习阶段,利用别人给的测试接口进行测试,并且进行一定的封装使用,一系列没有任何问题。然后再去进入自己开发阶段。【解决问题????】

  • 以上遇到的四个参数  URL(请求地址),METHOD_NAME(请求方法名),NAMESPACE(命名空间),SOAP_ACTION(这个我就不知道是什么)

     但我发现 SOAP_ACTION 好像是 NAMESPACE + METHOD_NAME 。不知道我请求的地址刚好是这样还是如何,但是也有看到是 空值的,但是我空值不通过,我采用的是这样方式。

  • 这次学习中并没有讲到 请求头 和 请求参数,那这些怎么传呢?

     百度搜索 Android ksoap2 可以参考一下这个链接 

    【1】https://blog.csdn.net/fjnu_se/article/details/90647663 可以得到参数传递的方式

     

 

     【2】https://www.cnblogs.com/bdsdkrb/p/9258099.html

     

 

  • 修改请求类 

  1. 1 package com.example.aust_app;
  2. 2
  3. 3
  4. 4 /*Created by wqy on 2019/11/8.*/
  5. 5
  6. 6 import android.content.Context;
  7. 7 import android.os.AsyncTask;
  8. 8
  9. 9 import com.example.aust_app.utils.LogUtil;
  10. 10 import com.example.aust_app.utils.ShareUtils;
  11. 11 import com.example.aust_app.utils.ToastTool;
  12. 12
  13. 13 import org.ksoap2.HeaderProperty;
  14. 14 import org.ksoap2.SoapEnvelope;
  15. 15 import org.ksoap2.serialization.SoapObject;
  16. 16 import org.ksoap2.serialization.SoapSerializationEnvelope;
  17. 17 import org.ksoap2.transport.HttpTransportSE;
  18. 18
  19. 19 import java.util.ArrayList;
  20. 20 import java.util.Map;
  21. 21 import java.util.Set;
  22. 22
  23. 23 public class WebRequest {
  24. 24
  25. 25 private String SOAP_ACTION = "";
  26. 26 private String NAMESPACE = "";
  27. 27 private String METHOD_NAME = "";
  28. 28 private String URL = "http://ip/name.asmx";
  29. 29
  30. 30 WebRequest request = null;
  31. 31 Context context = null;
  32. 32
  33. 33 public WebRequest(Context context) {
  34. 34 this.context = context;
  35. 35 URL = ShareUtils.getURL(context);
  36. 36 if (URL.equals(""))
  37. 37 ToastTool.showShortToast("请配置正确请求地址");
  38. 38
  39. 39 }
  40. 40
  41. 41 public static WebRequest init(Context context) {
  42. 42 return new WebRequest(context);
  43. 43 }
  44. 44
  45. 45 public String getSOAP_ACTION() {
  46. 46 return SOAP_ACTION;
  47. 47 }
  48. 48
  49. 49 public WebRequest setSOAP_ACTION(String SOAP_ACTION) {
  50. 50 this.SOAP_ACTION = SOAP_ACTION;
  51. 51 return this;
  52. 52 }
  53. 53
  54. 54 public String getNAMESPACE() {
  55. 55 return NAMESPACE;
  56. 56 }
  57. 57
  58. 58 public WebRequest setNAMESPACE(String NAMESPACE) {
  59. 59 this.NAMESPACE = NAMESPACE;
  60. 60 return this;
  61. 61 }
  62. 62
  63. 63 public String getMETHOD_NAME() {
  64. 64 return METHOD_NAME;
  65. 65 }
  66. 66
  67. 67 public WebRequest setMETHOD_NAME(String METHOD_NAME) {
  68. 68 this.METHOD_NAME = METHOD_NAME;
  69. 69 SOAP_ACTION += METHOD_NAME;
  70. 70 return this;
  71. 71 }
  72. 72
  73. 73 public String getURL() {
  74. 74 return URL;
  75. 75 }
  76. 76
  77. 77 public WebRequest setURL(String URL) {
  78. 78 this.URL = URL;
  79. 79 return this;
  80. 80 }
  81. 81
  82. 82
  83. 83 private SoapObject getInformation() {
  84. 84 SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
  85. 85
  86. 86 if (queryParamsMap != null && queryParamsMap.size() > 0) {
  87. 87 Set<String> keys = queryParamsMap.keySet();
  88. 88 for (String queryKey : keys) {
  89. 89 request.addProperty(queryKey, queryParamsMap.get(queryKey));
  90. 90 }
  91. 91 LogUtil.logi("param", "" + queryParamsMap);
  92. 92 }
  93. 93
  94. 94 SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
  95. 95 envelope.setOutputSoapObject(request);
  96. 96 envelope.dotNet = true;//很重要
  97. 97 try {
  98. 98 HttpTransportSE transportSE = new HttpTransportSE(URL);
  99. 99 if (headParamsMap != null)
  100. 100 transportSE.call(SOAP_ACTION, envelope, addHeadProperty(headParamsMap));
  101. 101 else
  102. 102 transportSE.call(SOAP_ACTION, envelope);
  103. 103 SoapObject result = (SoapObject) envelope.bodyIn; //获取到返回的结果,并强制转换成SoapObject对象
  104. 104 return result;
  105. 105 } catch (Exception e) {
  106. 106 e.printStackTrace();
  107. 107 if (postExecute != null) {
  108. 108 postExecute.onError(e.toString());
  109. 109 }
  110. 110
  111. 111 }
  112. 112 return null;
  113. 113 }
  114. 114
  115. 115 SoapObject result; //在子线程中请求webservice
  116. 116
  117. 117 class DownloadTask extends AsyncTask<Void, Integer, Boolean> {
  118. 118
  119. 119 @Override
  120. 120 protected Boolean doInBackground(Void... voids) {
  121. 121 result = getInformation();
  122. 122 return null;
  123. 123 }
  124. 124
  125. 125 @Override
  126. 126 protected void onPostExecute(Boolean aBoolean) {
  127. 127 StringBuilder builder = new StringBuilder();
  128. 128 //解析返回的数据
  129. 129 if (result != null)
  130. 130 for (int i = 0; i < result.getPropertyCount(); i++) {
  131. 131 builder.append(result.getProperty(i));
  132. 132 }
  133. 133 LogUtil.logi("result", "" + builder.toString());
  134. 134 if (postExecute != null) {
  135. 135 postExecute.getResult(builder.toString());
  136. 136 }
  137. 137 }
  138. 138 }
  139. 139
  140. 140 public void execute() {
  141. 141 new DownloadTask().execute();
  142. 142 }
  143. 143
  144. 144 PostExecuteListener postExecute;
  145. 145
  146. 146 interface PostExecuteListener {
  147. 147 void getResult(String result);
  148. 148
  149. 149 void onError(String result);
  150. 150 }
  151. 151
  152. 152 public PostExecuteListener getPostExecute() {
  153. 153 return postExecute;
  154. 154 }
  155. 155
  156. 156 public WebRequest setPostExecuteListener(PostExecuteListener postExecute) {
  157. 157 this.postExecute = postExecute;
  158. 158 return this;
  159. 159 }
  160. 160
  161. 161 Map<String, Object> queryParamsMap;
  162. 162 Map<String, Object> headParamsMap;
  163. 163
  164. 164 public Map<String, Object> getQueryParamsMap() {
  165. 165 return queryParamsMap;
  166. 166 }
  167. 167
  168. 168 public WebRequest setQueryParamsMap(Map<String, Object> queryParamsMap) {
  169. 169 this.queryParamsMap = queryParamsMap;
  170. 170 return this;
  171. 171 }
  172. 172
  173. 173 public Map<String, Object> getHeadParamsMap() {
  174. 174 return headParamsMap;
  175. 175 }
  176. 176
  177. 177 public WebRequest setHeadParamsMap(Map<String, Object> headParamsMap) {
  178. 178 this.headParamsMap = headParamsMap;
  179. 179 return this;
  180. 180 }
  181. 181
  182. 182 public ArrayList<HeaderProperty> addHeadProperty(Map<String, Object> headerParamsMap) {
  183. 183 ArrayList<HeaderProperty> headerProperty = new ArrayList<>();
  184. 184 //添加head参数
  185. 185 if (headerParamsMap != null && headerParamsMap.size() > 0) {
  186. 186 Set<String> keys = headerParamsMap.keySet();
  187. 187 for (String headerKey : keys) {
  188. 188 headerProperty.add(new HeaderProperty(headerKey, (String) headerParamsMap.get(headerKey)));
  189. 189 }
  190. 190 }
  191. 191 return headerProperty;
  192. 192 }
  193. 193
  194. 194 }

 

  • 在Activity中使用

  1. Map<String, Object> param = new HashMap<>();
  2. param.put("param", {{参数}});
  3. WebRequest.init(this)
  4. .setMETHOD_NAME("QueryItem")
  5. .setQueryParamsMap(param)
  6. .setPostExecuteListener(new WebRequest.PostExecuteListener() {
  7. @Override
  8. public void getResult(String result) {
  9. LogUtil.logi("TAG", result);//拿到返回结果
  10. }
  11. @Override
  12. public void onError(String result) {
  13. //请求错误的接口
  14. ToastTool.showShortToast("请求发生错误!");
  15. }
  16. })
  17. .execute();

 

【最后问题】

  在传参方式,四个参数都准备完毕的时候,遇到了一个问题就是:可以请求无参数的方法是成功的,但是有参数的后台方法请求得到的参数都是为空的。

这里一个很重要的就是(我是通过如下方式解决的,Java和PHP都要设置这样的一个属性)

  1.   envelope.dotNet = true;

  但在百度的时候解决方法也有很多,比如,命名空间后面要加 “/” ,如果以上方式并未成功,建议参考如下方式:

  

 

 【最后最后】

  温馨提示:webservice 也是网络请求,Android 清单文件不要忘记加 网络访问 的权限 。

 

原文链接:http://www.cnblogs.com/xqz0618/p/ksoap2.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号