我很难找到有关如何使用 Android 调用标准 SOAP/WSDL Web 服务的好信息。我所能找到的只是非常复杂的文档和对“kSoap2”的引用,然后是一些关于使用SAX手动解析它们的一些信息。好的,那很好,但现在是 2008 年,所以我认为应该有一些好的库来调用标准 Web 服务。
Web 服务基本上是在NetBeans中创建的。我希望 IDE 支持生成管道类。我只需要最简单/最优雅的方式来从基于 Android 的手机联系基于WSDL的 Web 服务。
我很难找到有关如何使用 Android 调用标准 SOAP/WSDL Web 服务的好信息。我所能找到的只是非常复杂的文档和对“kSoap2”的引用,然后是一些关于使用SAX手动解析它们的一些信息。好的,那很好,但现在是 2008 年,所以我认为应该有一些好的库来调用标准 Web 服务。
Web 服务基本上是在NetBeans中创建的。我希望 IDE 支持生成管道类。我只需要最简单/最优雅的方式来从基于 Android 的手机联系基于WSDL的 Web 服务。
Android 不提供任何类型的 SOAP 库。您可以自己编写,也可以使用类似kSOAP 2的东西。正如您所注意到的,其他人已经能够在他们自己的项目中编译和使用 kSOAP2,但我不必这样做。
迄今为止,Google 对向 Android 添加 SOAP 库表示兴趣不大。我对此的怀疑是,他们宁愿支持 Web 服务的当前趋势,转向基于 REST 的服务,并使用 JSON 作为数据封装格式。或者,使用 XMPP 进行消息传递。但这只是猜测。
目前,基于 XML 的 Web 服务在 Android 上是一项非常重要的任务。不了解 NetBeans,我无法谈论那里可用的工具,但我同意应该提供更好的库。XmlPullParser 有可能使您免于使用 SAX,但我对此知之甚少。
org.apache.http.impl.client.DefaultHttpClient
默认情况下包含在 Android SDK 中。这将使您连接到 WSDL。
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 服务。我的方法如下拨打电话。
HttpURLConnection
。getResonseCode
)。ErrorInput
在同一个 HTTPobject 上获取一个流并接收错误(如果有)。我已经为安卓手机实现了这个程序,并且运行成功。即使响应超过 700 KB,我也能够解析它。
SOAP 是一种不适合在 Android(或一般的移动设备)上使用的技术,因为它需要处理/解析开销。REST 服务是一种更轻量级的解决方案,这就是我的建议。Android 带有一个 SAX 解析器,使用起来相当简单。如果您绝对需要在移动设备上处理/解析 SOAP,那么我为您感到抱歉,我能提供的最佳建议就是不要使用 SOAP。
大约一年前,我正在阅读这个线程,试图弄清楚如何在 Android 上进行 SOAP 调用 - 使用 HttpClient 构建我自己的建议导致我为 Android 构建了自己的 SOAP 库:
基本上,它允许您构建信封以通过简单的 Java API 发送,然后自动将它们解析为您通过 XPath 定义的对象......例如:
<Dictionary>
<Id></Id>
<Name></Name>
</Dictionary>
变成:
@XMLObject("//Dictionary")
public class Dictionary {
@XMLField("Id")
private String id;
@XMLField("Name")
private String name;
}
我将它用于我自己的项目,但我认为它可能对其他人有所帮助,因此我花了一些时间将其分离出来并记录下来。如果你的一些可怜的灵魂在谷歌搜索“SOAP Android”时偶然发现了这个线程,我真的很喜欢它,他们可以试一试并获得一些好处。
不要忘记在您的项目中添加 ksoap2.jar 并在 AndroidManifest 文件中添加 INTERNET 权限
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);
}
}
}
我与 KSOAP 幽会;我选择了一种更简单的方法。
给定一个 WSDL 文件,为每个请求创建 SOAP 请求模板(例如:使用 SOAP UI),然后替换要在代码中传递的值。使用 DefaultHttpClient 实例将此数据发布到服务端点并获取响应流。使用 XML Pull 解析器解析响应流。
你可以看看WSClient++
我为 Android 平台创建了一个新的 SOAP 客户端。它使用的是 JAX-WS 生成的接口,但到目前为止它只是一个概念验证。
如果您有兴趣,请尝试该示例和/或在AndroidSOAP上观看源代码。
如果可以,请选择 JSON。Android 自带完整的 org.json 包
调用ksoap2方法。它工作得很好。
设置详细信息,例如
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);
然后得到结果
androidHttpTransport.call(SOAP_ACTION, envelope);
result = (SoapPrimitive)envelope.getResponse();
我希望从 Android 调用网络服务有所帮助。
几个月前,我在 j2ee 应用程序中使用 jax-ws Web 服务,我们使用CXF wsdl2java从 WSDL 文件生成 WS 客户端存根,并使用这些客户端存根使用 Web 服务。几周前,当我试图在 android 平台上以同样的方式使用 web 服务时,我做不到,因为 android jar 中没有所有的“jax-ws”支持类。那个时候我没有找到任何这样的工具(如果我没有有效地用谷歌搜索的话)来满足我的要求——
因此,我开发了自己的Android SOAP 客户端生成工具。您必须按照以下步骤操作:
例如:
ComplexOperationService service = new ComplexOperationService( );
ComplexOperation port= service.getComplexOperationPort();
SomeComplexRequest request = --Get some complex request----;
SomeComplexResp resp = port.operate( request );
我认为从 Android 应用程序调用 SOAP Web 服务 会对您有很大帮助。
如果您可以使用 JSON,则在使用 PHP 服务器和 Android 手机客户端开发应用程序服务中有一份白皮书、一个视频和示例代码。
按照 SOAP 方法执行这些步骤
从 WSDL 文件中,
为每个请求创建 SOAP 请求模板。
然后替换要在代码中传递的值。
使用 DefaultHttpClient 实例将此数据发布到服务端点。
获取响应流,最后
使用 XML Pull 解析器解析响应流。
如果您在调用 android 中的 Web 服务时遇到问题,那么您可以使用下面的代码来调用 Web 服务并获得响应。确保您的 Web 服务以数据表格式返回响应。如果您使用SQL Server数据库中的数据,此代码将为您提供帮助。如果您使用MYSQL,您需要更改一件事,只需用 DocumentElement 替换 句子中的单词NewDataSetobj2=(SoapObject) obj1.getProperty("NewDataSet");
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/
这是一个在 android 中使用 SOAP Web 服务的工作示例。
**注意 ::***不要忘记在您的项目中添加 ksoap2.jar 并在 AndroidManifest 文件中添加 INTERNET 权限*
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();
}
}
请下载并使用您的项目添加 SOAP 库文件文件名:ksoap2-android-assembly-3.4.0-jar-with-dependencies
清理应用程序,然后启动程序
这是 SOAP 服务调用的代码
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
为了您更好的参考, https://trinitytuts.com/load-data-from-soap-web-service-in-android-application/
谢谢。
您可以使用某些标头通过 http 执行肥皂调用作为 post。我在没有像 ksoap2 这样的额外库的情况下解决了这个问题 这是从肥皂服务获取订单的实时代码
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\">\n" +
" <soap:Header/>\n" +
" <soap:Body>\n" +
" <ser:GetAllOrdersOfShipment>\n" +
" <ser:CodeOfBranch></ser:CodeOfBranch>\n" +
" </ser:GetAllOrdersOfShipment>\n" +
" </soap:Body>\n" +
"</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
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;
}
}
添加肥皂 Libaray( ksoap2-android-assembly-3.2.0-jar-with-dependencies.jar
):
公共静态字符串 Fn_Confirm_CollectMoney_Approval(
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;
}
}