如何在Android上调用SOAP web服务

我在寻找关于如何使用Android调用标准SOAP/WSDL web服务的好信息时遇到了很多麻烦。我所能找到的都是非常复杂的文档和对“kSoap2”的引用,然后是一些关于使用SAX手动解析它的内容。好吧,这很好,但现在是2008年,所以我认为应该有一些调用标准web服务的好库。

web服务基本上就是在NetBeans中创建的服务。我希望有IDE支持来生成管道类。我只需要最简单/最优雅的方式来联系WSDL基于web服务从一个基于android的手机。

433278 次浏览

我相信您可以使用创建一个小型SOAP客户机。# EYZ1。

Android没有提供任何类型的SOAP库。您可以自己编写,也可以使用kSOAP 2之类的代码。正如您所注意到的,其他人已经能够在他们自己的项目中编译和使用kSOAP2,但我还没有这样做。

到目前为止,谷歌对向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是一种不适合在Android(或一般的移动设备)上使用的技术,因为它需要处理/解析开销。REST服务是一种轻量级的解决方案,这就是我的建议。Android自带SAX解析器,使用起来相当简单。如果您绝对需要在移动设备上处理/解析SOAP,那么我为您感到遗憾,我能提供的最好的建议就是不要使用SOAP。

的确,由于开销过大,SOAP并不是与移动设备进行数据交换的最佳选择。但是,您可能会发现自己处于无法控制服务器输出格式的情况。

所以,如果你必须坚持使用SOAP,这里有一个为Android补丁的kSOAP2库:
# EYZ0 < / p >

我和KSOAP幽会过;我选择了一个相当简单的方法。

给定一个WSDL文件,为每个请求创建SOAP请求模板(例如:使用SOAP UI),然后替换要在代码中传递的值。使用DefaultHttpClient实例将此数据发送到服务端点并获得响应流。使用XML Pull解析器解析响应流。

如果可以,选择JSON。Android自带完整的组织。json包

要从移动设备(尤其是Android手机)调用web服务,我使用了一种非常简单的方法。我没有使用任何web服务客户端API试图调用web服务。我打电话的方法如下。

  1. 创建一个简单的HTTP连接 使用Java标准API 李# EYZ0。< / >
  2. 组成SOAP请求。(你可以 SOAPUI的帮助来创建SOAP 李请求。)< / >
  3. 将doOutPut flag设置为true。
  4. 设置HTTP报头值 内容长度,内容 type和User-agent。不要忘记 设置Content-length值,因为它是强制的
  5. 将整个SOAP请求写入输出流。
  6. 调用方法建立连接和 接收响应(在我的情况下,我使用 李# EYZ0)。< / >
  7. 如果您收到的响应代码为
    1. 这意味着您成功调用web服务。
    2. 李< / ol > < / >
    3. 现在取相同的输入流 HTTP连接和接收 字符串对象。这个字符串对象是
    4. 如果响应码不是 200然后播放ErrorInput流 相同的HTTPobject和接收
    5. 解析接收到的响应 使用SAXParser(在我的情况下)或 DOMParaser或任何其他解析 李机制。< / >

    我已经在Android手机上实现了这个过程,并且它正在成功运行。我能够解析响应,即使它超过700 KB。

我希望从Android调用web服务能有所帮助。

你可以看看WSClient + +

我已经为Android平台创建了一个新的SOAP客户机。它使用一个JAX-WS生成的接口,但到目前为止它只是一个概念验证。

如果您感兴趣,请尝试示例和/或在AndroidSOAP观看源代码。

我认为从Android应用程序调用SOAP Web服务会对你有很大帮助。

如果你可以使用JSON,有一个白皮书,一个视频和示例。代码在使用PHP服务器和Android手机客户端开发应用程序服务

调用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上执行SOAP调用——使用HttpClient构建我自己的SOAP库的建议导致我为Android构建了自己的SOAP库:

< a href = " https://github.com/AlexGilleran/IceSoap " > IceSoap < / >

基本上,它允许您构建通过简单的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”时偶然发现这条线索,可以尝试一下,并得到一些好处。

几个月前,我在j2ee应用程序中使用jax-ws web服务,在那里我们使用CXF wsdl2java从WSDL文件生成WS客户端存根,并使用这些客户端存根消费web服务。几周前,当我试图在android平台上以同样的方式使用web服务时,我不能,因为android jar中没有所有的“jax-ws”支持类。那时候我没有找到任何这样的工具(如果我不是失败谷歌有效)来满足我的要求——

  • 从WSDL获取客户端存根。
  • 并使用一些参数调用服务(java业务请求 对象)。李< / >
  • 获取响应业务对象。

所以,我开发了自己的Android SOAP客户端生成工具。你需要遵循以下步骤:

  • 从WSDL获取WS客户端存根,将其放入您的项目中。
  • Say for Some Service" ComplexOperationService",实例化 服务,获取端点端口并调用服务方法,并从Web服务获取响应:

例如:

ComplexOperationService service = new ComplexOperationService( );
ComplexOperation port= service.getComplexOperationPort();
SomeComplexRequest request = --Get some complex request----;
SomeComplexResp resp = port.operate( request  );
  • 您不需要关心服务类/请求/响应类或任何其他类以及方法,因为您知道它们都是从WSDL生成的。
  • 当然,您不需要知道soap动作/信封/名称空间等等。就像我们开发人员一直做的那样调用这个方法。

如果你在android中调用Web服务有问题,那么 您可以使用下面的代码来调用web服务并获得响应。确保您的web服务返回数据表格格式中的响应。如果您使用SQL Server数据库中的数据,这段代码将帮助您。如果你使用MYSQL,你需要改变一件事,只需将单词NewDataSet从句子obj2=(SoapObject) obj1.getProperty("NewDataSet");替换为DocumentElement

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
}
}

如果你有任何问题,你可以写信给我。

通过SOAP方法遵循这些步骤

从WSDL文件中,

  • 为每个请求创建SOAP请求模板。

  • 然后替换要在代码中传递的值。

  • 使用DefaultHttpClient实例将该数据POST到服务端点。

  • 获取响应流,最后

  • 使用XML Pull解析器解析响应流。

要从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;
}
}

不要忘记在你的项目中添加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);
}


}
}
我建议你看看一个非常有用的工具,它对我帮助很大。的人 负责那个项目的人也很有帮助。 www.wsdl2code.com/ < / p >

这是一个在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();
}
}

对我来说,最简单的方法是使用好的工具来生成所有必需的类。我个人使用这个网站:

http://easywsdl.com/ < a href = " http://easywsdl.com/ " > < / >

它支持相当复杂的web服务,并使用ksoap2。

请下载并添加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

为了更好的参考, # EYZ0 < / p >

谢谢。

添加Soap库(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;
}


}
你可以在http上使用特定的报头执行soap调用。 我没有像ksoap2这样的附加库就解决了这个问题 这是从soap服务

获得订单的实时代码
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;
}