How to call a SOAP web service on Android
我在查找如何使用Android调用标准SOAP / WSDL Web服务方面遇到很多麻烦。 我所能找到的都是非常复杂的文档和对"kSoap2"的引用,然后是一些关于使用SAX手动解析它的一些内容。 好的,这很好,但是它是2008年,所以我认为应该有一些很好的库来调用标准的Web服务。
Web服务基本上是在NetBeans中创建的。 我想有IDE支持生成管道类。 我只需要最简单/最优雅的方式来从基于Android的手机联系基于WSDL的Web服务。
Android不提供任何类型的SOAP库。您可以编写自己的,也可以使用kSOAP 2之类的东西。正如您所说,其他人已经能够在自己的项目中编译和使用kSOAP2,但我没有必要。
到目前为止,Google已经表明,对于向Android添加SOAP库几乎没有兴趣。我对此的怀疑是,他们宁愿支持当前基于REST服务的Web服务趋势,并使用JSON作为数据封装格式。或者,使用XMPP进行消息传递。但这只是猜想。
目前,基于XML的Web服务在Android上是一项稍微不重要的任务。不了解NetBeans,我不能说那里提供的工具,但我同意应该有更好的库。 XmlPullParser可能会使您无法使用SAX,但我对此并不了解。
默认情况下,
1 2 3 4 | HttpClient httpClient = new DefaultHttpClient(); HttpContext localContext = new BasicHttpContext(); HttpGet httpGet = new HttpGet("http://www.example.com/" + URL); HttpResponse response = httpClient.execute(httpGet, localContext); |
确实,由于它的开销,SOAP不是与移动设备进行数据交换的最佳选择。但是,您可能会发现自己处于无法控制服务器输出格式的情况。
所以,如果你必须坚持使用SOAP,那么在这里有一个为Android修补的kSOAP2库:
http://code.google.com/p/ksoap2-android/
要从移动设备(特别是在Android手机上)调用Web服务,我使用了一种非常简单的方法来执行此操作。我没有使用任何Web服务客户端API来尝试调用Web服务。我的方法是拨打电话如下。
使用Java标准API
帮助SOAPUI制作SOAP
请求。)
内容长度,内容
类型和用户代理。不要忘记
设置Content-length值,因为它是必需的。
收到回复(在我的情况下,我用过
HTTP连接并接收
字符串对象。这个字符串对象是
SOAP响应。
200然后打开
相同的HTTP对象并接收
如果有错误。
使用SAXParser(在我的情况下)或
DOMParaser或任何其他解析
机制。
我已经为Android手机实现了这个程序,并且它已成功运行。我能够解析响应,即使它超过700 KB。
SOAP是一种不适合在Android(或一般移动设备)上使用的技术,因为它需要处理/解析开销。 REST服务是一种更轻量级的解决方案,这就是我的建议。 Android附带一个SAX解析器,使用起来相当简单。如果您绝对需要在移动设备上处理/解析SOAP,那么我为您感到遗憾,我能提供的最佳建议就是不使用SOAP。
DON'T FORGET TO ADD ksoap2.jar in your project and also add the
INTERNET permission in AndroidManifest file
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 | import org.ksoap2.SoapEnvelope; import org.ksoap2.serialization.PropertyInfo; import org.ksoap2.serialization.SoapObject; import org.ksoap2.serialization.SoapPrimitive; import org.ksoap2.serialization.SoapSerializationEnvelope; import org.ksoap2.transport.HttpTransportSE; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class WebserviceActivity extends Activity { private static final String NAMESPACE ="https://api.authorize.net/soap/v1/"; private static final String URL ="https://apitest.authorize.net/soap/v1/Service.asmx?wsdl"; private static final String SOAP_ACTION ="https://api.authorize.net/soap/v1/AuthenticateTest"; private static final String METHOD_NAME ="AuthenticateTest"; private TextView lblResult; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); lblResult = (TextView) findViewById(R.id.tv); SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); request.addProperty("name","44vmMAYrhjfhj66fhJN"); request.addProperty("transactionKey","9MDQ7fghjghjh53H48k7e7n"); SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.setOutputSoapObject(request); HttpTransportSE androidHttpTransport = new HttpTransportSE(URL); try { androidHttpTransport.call(SOAP_ACTION, envelope); //SoapPrimitive resultsRequestSOAP = (SoapPrimitive) envelope.getResponse(); // SoapPrimitive resultsRequestSOAP = (SoapPrimitive) envelope.getResponse(); SoapObject resultsRequestSOAP = (SoapObject) envelope.bodyIn; lblResult.setText(resultsRequestSOAP.toString()); System.out.println("Response::"+resultsRequestSOAP.toString()); } catch (Exception e) { System.out.println("Error"+e); } } } |
大约一年前,我正在阅读这个线程,试图找出如何在Android上进行SOAP调用 - 使用HttpClient构建我自己的建议导致我为Android构建自己的SOAP库:
IceSoap
基本上,它允许您构建信封以通过简单的Java API发送,然后自动将它们解析为您通过XPath定义的对象...例如:
1 2 3 4 | <Dictionary> <Id></Id> <Name></Name> </Dictionary> |
变为:
1 2 3 4 5 6 7 8 | @XMLObject("//Dictionary") public class Dictionary { @XMLField("Id") private String id; @XMLField("Name") private String name; } |
我正在将它用于我自己的项目,但我认为它可能会帮助其他人,所以我花了一些时间把它分开并记录下来。我真的很喜欢它,如果你的一些可怜的灵魂在谷歌搜索"SOAP Android"时偶然发现这个线程可能会给它带来一些好处。
我跟KSOAP约会了;我选择了一种相当简单的方法。
给定WSDL文件,为每个请求创建SOAP请求模板(例如:使用SOAP UI),然后替换要在代码中传递的值。使用DefaultHttpClient实例将此数据发布到服务端点并获取响应流。使用XML Pull解析器解析响应流。
你可以看看WSClient ++
我为Android平台创建了一个新的SOAP客户端。它使用的是JAX-WS生成的接口,但到目前为止它只是一个概念验证。
如果您有兴趣,请尝试示例和/或在AndroidSOAP上观看来源。
如果可以,请选择JSON。 Android附带完整的org.json包
调用ksoap2方法。它工作得非常好。
设置细节,比如
1 2 3 4 5 6 7 8 9 | private static String mNAMESPACE=null; private static String mURL=null; public static Context context=null; SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.dotNet = true; envelope.setOutputSoapObject(Request); envelope.addMapping(mNAMESPACE,"UserCredentials",new UserCredendtials().getClass()); AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(mURL); |
然后得到结果呢
1 2 | androidHttpTransport.call(SOAP_ACTION, envelope); result = (SoapPrimitive)envelope.getResponse(); |
我希望从Android调用Web服务有所帮助。
几个月前我在j2ee应用程序中使用jax-ws web服务,我们使用CXF wsdl2java从WSDL文件生成WS客户端存根,并使用这些客户端存根来使用Web服务。几周前,当我试图以相同的方式在Android平台上使用Web服务时,我无法,因为android jar并没有所有"jax-ws"支持类。那个时候我没有找到任何这样的工具(如果我没有有效地谷歌),以满足我的要求 -
- 从WSDL获取客户端存根。
-
并使用一些参数调用服务(java业务请求
宾语)。 - 获取响应业务对象。
所以,我开发了自己的Android SOAP客户端生成工具。你必须遵循以下步骤:
- 从WSDL获取WS Client Stub,将其放入您的项目中。
-
说一些服务"ComplexOperationService",实例化
服务,获取端点端口并调用服务方法,并从Web服务获取响应:
例如:
1 2 3 4 | ComplexOperationService service = new ComplexOperationService( ); ComplexOperation port= service.getComplexOperationPort(); SomeComplexRequest request = --Get some complex request----; SomeComplexResp resp = port.operate( request ); |
- 您不需要关心服务类/ req /响应类或任何其他类和方法,因为您知道它们都是从WSDL生成的。
- 当然,你不需要知道soap action / envelop / namespace等。只需像我们一样调用方法,开发人员一直这样做。
我相信你可以用Axis创建一个小型的SOAP客户端。轴安装说明。
我认为来自Android应用程序的Call SOAP Web Service将为您提供很多帮助。
按照SOAP方法执行这些步骤
从WSDL文件中
-
为每个请求创建SOAP请求模板。
-
然后替换要在代码中传递的值。
-
使用DefaultHttpClient实例将此数据发布到服务端点。
-
最后得到响应流
-
使用XML Pull解析器解析响应流。
对我来说,最简单的方法是使用好的工具来生成所有必需的类。我个人使用这个网站:
http://easywsdl.com/
它支持相当复杂的Web服务并使用kso??ap2。
如果您可以使用JSON,那么在开发带有PHP服务器和Android手机客户端的应用程序服务中有一个白皮书,一个视频和sample.code。
如果你有关于在Android中调用Web服务的问题那么
您可以使用以下代码来调用Web服务并获得响应。确保您的Web服务以数据表格式返回响应。如果您使用SQL Server数据库中的数据,此代码将帮助您。如果您使用MYSQL,您需要更改一件事,只需用DocumentElement替换句子
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 | void callWebService(){ private static final String NAMESPACE ="http://tempuri.org/"; // for wsdl it may be package name i.e http://package_name private static final String URL ="http://localhost/sample/services/MyService?wsdl"; // you can use IP address instead of localhost private static final String METHOD_NAME ="Function_Name"; private static final String SOAP_ACTION ="urn:" + METHOD_NAME; SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); request.addProperty("parm_name", prm_value);// Parameter for Method SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.dotNet = true;// **If your Webservice in .net otherwise remove it** envelope.setOutputSoapObject(request); HttpTransportSE androidHttpTransport = new HttpTransportSE(URL); try { androidHttpTransport.call(SOAP_ACTION, envelope);// call the eb service // Method } catch (Exception e) { e.printStackTrace(); } // Next task is to get Response and format that response SoapObject obj, obj1, obj2, obj3; obj = (SoapObject) envelope.getResponse(); obj1 = (SoapObject) obj.getProperty("diffgram"); obj2 = (SoapObject) obj1.getProperty("NewDataSet"); for (int i = 0; i < obj2.getPropertyCount(); i++) { // the method getPropertyCount() and return the number of rows obj3 = (SoapObject) obj2.getProperty(i); obj3.getProperty(0).toString();// value of column 1 obj3.getProperty(1).toString();// value of column 2 // like that you will get value from each column } } |
如果您对此有任何疑问,可以写信给我..
我建议查看一个非常有用的工具,帮助了我很多。伙计们
谁也照顾这个项目非常有帮助。
www.wsdl2code.com/
请下载并在项目中添加SOAP库文件
文件名:ksoap2-android-assembly-3.4.0-jar-with-dependencies
清理应用程序,然后启动程序
这是SOAP服务调用的代码
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 | String SOAP_ACTION ="YOUR_ACTION_NAME"; String METHOD_NAME ="YOUR_METHOD_NAME"; String NAMESPACE ="YOUR_NAME_SPACE"; String URL ="YOUR_URL"; SoapPrimitive resultString = null; try { SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME); addPropertyForSOAP(Request); SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); soapEnvelope.dotNet = true; soapEnvelope.setOutputSoapObject(Request); HttpTransportSE transport = new HttpTransportSE(URL); transport.call(SOAP_ACTION, soapEnvelope); resultString = (SoapPrimitive) soapEnvelope.getResponse(); Log.i("SOAP Result","Result Celsius:" + resultString); } catch (Exception ex) { Log.e("SOAP Result","Error:" + ex.getMessage()); } if(resultString != null) { return resultString.toString(); } else{ return"error"; } |
结果可能是JSONObject或JSONArray或String
为了更好的参考,
谢谢。
这是在android中使用SOAP Web服务的一个工作示例。
**注意:: ***不要忘记在项目中添加ksoap2.jar,并在AndroidManifest文件中添加INTERNET权限*
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 | public final String WSDL_TARGET_NAMESPACE ="http://tempuri.org/"; public final String METHOD_NAME ="FahrenheitToCelsius"; public final String PROPERTY_NAME ="Fahrenheit"; public final String SOAP_ACTION ="http://tempuri.org/FahrenheitToCelsius"; public final String SOAP_ADDRESS ="http://www.w3schools.com/webservices/tempconvert.asmx"; private class TestAsynk extends AsyncTask<String, Void, String> { @Override protected void onPostExecute(String result) { super.onPostExecute(result); Toast.makeText(getApplicationContext(), String.format("%.2f", Float.parseFloat(result)), Toast.LENGTH_SHORT).show(); } @Override protected String doInBackground(String... params) { SoapObject request = new SoapObject(WSDL_TARGET_NAMESPACE, METHOD_NAME); request.addProperty(PROPERTY_NAME, params[0]); SoapSerializationEnvelope envelope = new SoapSerializationEnvelope( SoapEnvelope.VER11); envelope.dotNet = true; envelope.setOutputSoapObject(request); HttpTransportSE androidHttpTransport = new HttpTransportSE( SOAP_ADDRESS); Object response = null; try { androidHttpTransport.call(SOAP_ACTION, envelope); response = envelope.getResponse(); Log.e("Object response", response.toString()); } catch (Exception e) { e.printStackTrace(); } return response.toString(); } } |
您可以通过http使用某些标题执行soap调用。
我没有像ksoap2这样的额外库就解决了这个问题
这是从肥皂服务获取订单的实时代码
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 | private static HashMap<String,String> mHeaders = new HashMap<>(); static { mHeaders.put("Accept-Encoding","gzip,deflate"); mHeaders.put("Content-Type","application/soap+xml"); mHeaders.put("Host","35.15.85.55:8080"); mHeaders.put("Connection","Keep-Alive"); mHeaders.put("User-Agent","AndroidApp"); mHeaders.put("Authorization","Basic Q2xpZW50NTkzMzppMjR3s2U="); // optional }public final static InputStream receiveCurrentShipments(String stringUrlShipments) { int status=0; String xmlstring="<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ser="http://35.15.85.55:8080/ServiceTransfer"> " + " <soap:Header/> " + " <soap:Body> " + " <ser:GetAllOrdersOfShipment> " + " <ser:CodeOfBranch></ser:CodeOfBranch> " + " </ser:GetAllOrdersOfShipment> " + " </soap:Body> " + "</soap:Envelope>"; StringBuffer chaine = new StringBuffer(""); HttpURLConnection connection = null; try { URL url = new URL(stringUrlShipments); connection = (HttpURLConnection) url.openConnection(); connection.setRequestProperty("Content-Length", xmlstring.getBytes().length +""); connection.setRequestProperty("SOAPAction","http://35.15.85.55:8080/ServiceTransfer/GetAllOrdersOfShipment"); for(Map.Entry<String, String> entry : mHeaders.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); connection.setRequestProperty(key,value); } connection.setRequestMethod("POST"); connection.setDoInput(true); OutputStream outputStream = connection.getOutputStream(); outputStream.write(xmlstring.getBytes("UTF-8")); outputStream.close(); connection.connect(); status = connection.getResponseCode(); } catch (ProtocolException e) { e.printStackTrace(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { Log.i("HTTP Client","HTTP status code :" + status); } InputStream inputStream = null; try { inputStream = connection.getInputStream(); } catch (IOException e) { e.printStackTrace(); } return inputStream; } |
要从android调用SOAP Web服务,请尝试使用此客户端
不要忘记在你的java构建路径中添加ksoap2-android.jar
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 | public class WsClient { private static final String SOAP_ACTION ="somme"; private static final String OPERATION_NAME ="somme"; private static final String WSDL_TARGET_NAMESPACE ="http://example.ws"; private static final String SOAP_ADDRESS ="http://192.168.1.2:8080/axis2/services/Calculatrice?wsdl"; public String caclculerSomme() { String res = null; SoapObject request = new SoapObject(WSDL_TARGET_NAMESPACE, OPERATION_NAME); request.addProperty("a","5"); request.addProperty("b","2"); SoapSerializationEnvelope envelope = new SoapSerializationEnvelope( SoapEnvelope.VER11); envelope.dotNet = true; envelope.setOutputSoapObject(request); HttpTransportSE httpTransport = new HttpTransportSE(SOAP_ADDRESS); try { httpTransport.call(SOAP_ACTION, envelope); String result = envelope.getResponse().toString(); res = result; System.out.println("############# resull is :" + result); } catch (Exception exception) { System.out.println("########### ERRER" + exception.getMessage()); } return res; } } |
添加Soap Libaray(
public static String Fn_Confirm_CollectMoney_Approval(
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 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | HashMap < String, String > str1, HashMap < String, String > str2, HashMap < String, String > str3) { Object response = null; String METHOD_NAME ="CollectMoney"; String NAMESPACE ="http://xxx/yyy/xxx"; String URL ="http://www.w3schools.com/webservices/tempconvert.asmx"; String SOAP_ACTION =""; try { SoapObject RequestParent = new SoapObject(NAMESPACE, METHOD_NAME); SoapObject Request1 = new SoapObject(NAMESPACE,"req"); PropertyInfo pi = new PropertyInfo(); Set mapSet1 = (Set) str1.entrySet(); Iterator mapIterator1 = mapSet1.iterator(); while (mapIterator1.hasNext()) { Map.Entry mapEntry = (Map.Entry) mapIterator1.next(); String keyValue = (String) mapEntry.getKey(); String value = (String) mapEntry.getValue(); pi = new PropertyInfo(); pi.setNamespace("java:com.xxx"); pi.setName(keyValue); pi.setValue(value); Request1.addProperty(pi); } mapSet1 = (Set) str3.entrySet(); mapIterator1 = mapSet1.iterator(); while (mapIterator1.hasNext()) { Map.Entry mapEntry = (Map.Entry) mapIterator1.next(); // getKey Method of HashMap access a key of map String keyValue = (String) mapEntry.getKey(); // getValue method returns corresponding key's value String value = (String) mapEntry.getValue(); pi = new PropertyInfo(); pi.setNamespace("java:com.xxx"); pi.setName(keyValue); pi.setValue(value); Request1.addProperty(pi); } SoapObject HeaderRequest = new SoapObject(NAMESPACE,"XXX"); Set mapSet = (Set) str2.entrySet(); Iterator mapIterator = mapSet.iterator(); while (mapIterator.hasNext()) { Map.Entry mapEntry = (Map.Entry) mapIterator.next(); // getKey Method of HashMap access a key of map String keyValue = (String) mapEntry.getKey(); // getValue method returns corresponding key's value String value = (String) mapEntry.getValue(); pi = new PropertyInfo(); pi.setNamespace("java:com.xxx"); pi.setName(keyValue); pi.setValue(value); HeaderRequest.addProperty(pi); } Request1.addSoapObject(HeaderRequest); RequestParent.addSoapObject(Request1); SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope( SoapEnvelope.VER10); soapEnvelope.dotNet = false; soapEnvelope.setOutputSoapObject(RequestParent); HttpTransportSE transport = new HttpTransportSE(URL, 120000); transport.debug = true; transport.call(SOAP_ACTION, soapEnvelope); response = (Object) soapEnvelope.getResponse(); int cols = ((SoapObject) response).getPropertyCount(); Object objectResponse = (Object) ((SoapObject) response) .getProperty("Resp"); SoapObject subObject_Resp = (SoapObject) objectResponse; modelObject = new ResposeXmlModel(); String MsgId = subObject_Resp.getProperty("MsgId").toString(); modelObject.setMsgId(MsgId); String OrgId = subObject_Resp.getProperty("OrgId").toString(); modelObject.setOrgId(OrgId); String ResCode = subObject_Resp.getProperty("ResCode").toString(); modelObject.setResCode(ResCode); String ResDesc = subObject_Resp.getProperty("ResDesc").toString(); modelObject.setResDesc(ResDesc); String TimeStamp = subObject_Resp.getProperty("TimeStamp") .toString(); modelObject.setTimestamp(ResDesc); return response.toString(); } catch (Exception ex) { ex.printStackTrace(); return null; } } |