我正在开发一个Android应用程序,它需要连接到.NET SOAP Web服务并从响应中生成/填充许多对象。我对Web服务和SOAP都很陌生,而且对Android来说相对较新。 Web服务已经构建(不是由我)。
我一直在尝试查找有关在Android中连接到SOAP Web服务的信息。这两个基本建议似乎是:
我已经查看了KSOAP2的各种教程,但它们似乎只处理最基本的原始类型,例如发送2个int以获得1个int,或者发送和接收字符串;但是,我需要来回发送自定义对象。
是否可以使用KSOAP2发送和接收自定义对象?如果是这样,这有多容易/困难?是否必须解析XML以手动创建/填充对象"?
修改/更新: 在尝试连接到现有的webservice(接受一个String并返回一个复杂的对象)并获得错误之后,我决定尝试一种更简单的方法。我连接到一个不带参数的简单web服务,并返回一个int。这个更简单的Web服务托管在与原始Web服务相同的位置,简单的Web服务现在可以正常使用。
进一步更新: 一切正常!事实证明我只是有一个大写错误,它抛弃了我的参数。
最后一个问题是"国家"与#34;国家"。这是soapUI生成的代码:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
<soapenv:Header/>
<soapenv:Body>
<tem:GetClientByNationalID>
<!--Optional:-->
<tem:nationalID>XXXXXXX</tem:nationalID>
</tem:GetClientByNationalID>
</soapenv:Body>
</soapenv:Envelope>
我的Java生成的请求代码:
<v:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/envelope/">
<v:Header />
<v:Body>
<GetClientByNationalID xmlns="http://tempuri.org/" id="o0" c:root="1">
<NationalID i:type="d:string">
XXXXXXXX
</NationalID>
</GetClientByNationalID>
</v:Body>
</v:Envelope>
我的最终java代码是:
public void webServiceCall() {
String NAMESPACE = "http://tempuri.org/";
String METHOD_NAME = "GetClientByNationalID";
String SOAP_ACTION = "http://tempuri.org/IClientService/GetClientByNationalID";
// unsecure service
String URL = "http://XXXXXXXXXXXXXXXXXXXX.net/FPUnSecureService/ClientService.svc";
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
String clientID = "XXXXXXX";
PropertyInfo pi = new PropertyInfo();
pi.setName("nationalID");
pi.setValue(clientID);
pi.setType(clientID.getClass());
request.addProperty(pi);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
envelope.addMapping(NAMESPACE, "GetClientByNationalID", new ClientID().getClass());
Marshal floatMarshal = new MarshalFloat();
floatMarshal.register(envelope);
HttpTransportSE t = new HttpTransportSE(URL);
ClientID client = new ClientID();
t.debug = true;
try {
Log.i("webServiceCall", "Trying call to web service");
t.call(SOAP_ACTION, envelope);
SoapObject response = (SoapObject) envelope.getResponse();
Log.i("success", response.getPropertyAsString(0));
Log.i("success", response.getPropertyAsString(1));
Log.i("success", response.getPropertyAsString(2));
Log.i("success", response.getPropertyAsString(3));
Log.i("success", response.getPropertyAsString(4));
} catch (Exception e) {
Log.e("webServiceCall", "Error calling webservice.");
e.printStackTrace();
System.out.println("Request: " + t.requestDump);
System.out.println("Response: " + t.responseDump);
}
}
我仍然对这些问题感到困惑:
envelope.addMapping(NAMESPACE, "GetClientByNationalID", new ClientID().
Marshal floatMarshal = new MarshalFloat();
floatMarshal.register(envelope);
我认为当我将一个物体作为参数传递时,我添加了元帅部分,我不确定我是否还需要它们。我也不确定addMapping调用,以及我应该拥有的内容。谢谢。
答案 0 :(得分:1)
使用ksoap2,并通过以下链接使用代码示例检查我的答案:Link1,link2,link3。我写了一些细节,可以帮助您了解如何开始编码。
如果你需要帮助,请告诉我。
更新(回答有关映射和编组的问题)
当您通过soap信封发送复杂类型(即对象)时,请使用addMapping。 Web服务如何识别复杂类型?你需要在本地创建一个实现kvmserializable的类(在我的链接中提到),它将与服务器上的对象具有相同的参数,然后你需要在它和映射的类之间添加映射在服务器上对它进行处理,以便在服务器上解析时,它知道服务器上的这个复杂类型 X 映射到类 X 。因此,如果您不是发送复杂类型,则不需要添加映射。( PS:我发现您没有发送复杂类型,因为nationalID是string类型.IF可以说nationalID是一种复杂类型 Z 你会这样做:addMapping(NAMESPACE,Z.class.getSimpleName(),Z.class))
对于编组,它使用java序列化将对象更改为要在Web服务上解组的数据流。因此,当您发送复杂类型时,根据我的经验,添加编组以通过序列化将复杂类型更改为数据流是一种很好的做法。如果你发现你不需要它只是不添加它,但它总是很好理解那里的选项。
答案 1 :(得分:0)