Ksoap2 Android - 如何为复杂对象的子属性指定命名空间?
Posted
技术标签:
【中文标题】Ksoap2 Android - 如何为复杂对象的子属性指定命名空间?【英文标题】:Ksoap2 Android - how to specify a namespace for the child properties of a complex object? 【发布时间】:2012-03-24 03:50:51 【问题描述】:我正在尝试使用 KSoap2 android 将复杂对象上传到 WCF 网络服务,但在执行此操作时遇到了一些困难。当我使用 SoapUI 并手动填写数据时,我已经成功调用了 web 服务。成功的 SoapUI 生成请求如下:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" xmlns:fpm="http://schemas.datacontract.org/2004/07/FPMobileServices">
<soapenv:Header/>
<soapenv:Body>
<tem:CommitOne>
<tem:qr>
<fpm:ClientID>8aa2f6a4-4d15-4b4c-9cac-fb2478d0d27a</fpm:ClientID>
<fpm:CreatedBy>admin</fpm:CreatedBy>
<fpm:CreatedDate>2012-03-01T19:50:37</fpm:CreatedDate>
<fpm:DimensionID>8a02a339-b5a7-4c76-b95f-5891ef57736d</fpm:DimensionID>
<fpm:ImageID>b76c7bcc-a8f8-49ff-94c6-08cd2e05b1a8</fpm:ImageID>
<fpm:IndicatorID>4637b333-701d-4d03-a708-4de48569be84</fpm:IndicatorID>
<fpm:LoanOperationNumber>6-2011-72978</fpm:LoanOperationNumber>
<fpm:ModifiedBy>admin</fpm:ModifiedBy>
<fpm:ModifiedDate>2012-03-01T19:50:37</fpm:ModifiedDate>
<fpm:QuestionaireCompletedDate>2012-03-01T19:50:54</fpm:QuestionaireCompletedDate>
<fpm:QuestionnaireID>99967f70-8161-4922-929f-03136a389ba6</fpm:QuestionnaireID>
<fpm:ResultID>95fa03b5-80af-479d-9dec-f2bf94baf3cd</fpm:ResultID>
<fpm:ResultWeighting>0</fpm:ResultWeighting>
<fpm:StatusLevelID>03a91cd6-93cd-4503-a676-efa2967e82a7</fpm:StatusLevelID>
<fpm:UploadID>141D6A1F-8FFD-4CA4-8073-009338F22B13</fpm:UploadID>
</tem:qr>
</tem:CommitOne>
</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>
<CommitOne xmlns="http://tempuri.org/" id="o0" c:root="1">
<qr>
<ClientID>8aa2f6a4-4d15-4b4c-9cac-fb2478d0d27a</ClientID>
<LoanOperationNumber>6-2011-72978</LoanOperationNumber>
<CreatedBy i:null="true" />
<CreatedDate>2012-03-01T19:50:37</CreatedDate>
<DimensionID>8a02a339-b5a7-4c76-b95f-5891ef57736d</DimensionID>
<ImageID>b76c7bcc-a8f8-49ff-94c6-08cd2e05b1a8</ImageID>
<IndicatorID>4637b333-701d-4d03-a708-4de48569be84</IndicatorID>
<ModifiedBy i:null="true" />
<ModifiedDate i:null="true" />
<QuestionnaireCompletedDate>2012-03-01T19:50:54</QuestionnaireCompletedDate>
<QuestionnaireID>99967f70-8161-4922-929f-03136a389ba6</QuestionnaireID>
<ResultID i:type="d:string">95fa03b5-80af-479d-9dec-f2bf94baf3cc</ResultID>
<ResultWeighting>0</ResultWeighting>
<StatusLevelID>03a91cd6-93cd-4503-a676-efa2967e82a7</StatusLevelID>
<UploadID i:type="d:string">8ffa3665-b691-486f-91a0-ebbe8575896c</UploadID>
</qr>
</CommitOne>
</v:Body>
两者之间的主要区别似乎是前缀/命名空间。由于某种原因,当“qr”对象到达我的 .NET 代码时,它的所有属性都是空/零。
我在我的 java 代码中尝试了 2 种不同的方法,试图将我的“qr”对象设置为 PropertyInfo:
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
// build request object
PropertyInfo qrPi = new PropertyInfo();
qrPi.setName("qr");
qrPi.setType(qr.getClass());
qrPi.setValue(qr);
request.addProperty(qrPi);
还将我的“qr”设置为 SoapObject,然后使用 .addProperty:
SoapObject result = new SoapObject(NAMESPACE, "qr");
result.addProperty("ClientID", (String) qr.getClientID());
result.addProperty("CreatedBy", (String) qr.getCreatedBy());
result.addProperty("CreatedDate", (String) qr.getCreatedDate());
result.addProperty("DimensionID", (String) qr.getDimensionID());
result.addProperty("ImageID", (String) qr.getImageID());
result.addProperty("IndicatorID", (String) qr.getIndicatorID());
result.addProperty("LoanOperationNumber", (String) qr.getLoanOperationNumber());
result.addProperty("ModifiedBy", (String) qr.getModifiedBy());
result.addProperty("ModifiedDate", (String) qr.getModifiedDate());
result.addProperty("QuestionnaireCompletedDate", (String) qr.getQuestionnaireCompletedDate());
result.addProperty("QuestionnaireID", (String) qr.getQuestionnaireID());
result.addProperty("ResultID", (String) qr.getResultID());
result.addProperty("ResultWeighting", qr.getResultWeighting());
result.addProperty("StatusLevelID", (String) qr.getStatusLevelID());
result.addProperty("UploadID", (String) qr.getUploadID());
request.addSoapObject(result);
但是这两种方法都会得到相同的结果——当我的“qr”对象进入我的网络服务时,它的所有字段都是空的。我一直在 *** 上寻找类似的问题并找到 this,但我不知道如何将其应用于我自己的案例。
任何人都可以帮助了解情况吗?
【问题讨论】:
【参考方案1】:不确定我是否应该回答自己的问题,但我已经找到了解决方案,并将其留给遇到类似问题的任何人。
关键是不同的命名空间。在 SoapUI 生成的示例中,我们可以看到子元素(ClientID 等)使用 fpm 命名空间,而它们上面的元素使用 tem 命名空间。为了显式指定这些子元素的命名空间,我更改了上面讨论的第二种方法 - 我为每个子元素创建了 PropertyInfo 对象并将它们添加到 SoapObject。
而不是使用:
result.addProperty(String "ClientID", Object qr.getClientID());
我用过:
PropertyInfo pi = new PropertyInfo();
pi.setNamespace(QR_NAMESPACE);
pi.setType(PropertyInfo.STRING_CLASS);
pi.setName("ClientID");
pi.setValue(qr.getClientID());
result.addProperty(pi);
当我对所有属性执行此操作时,它运行良好。
希望有一天这对其他人有所帮助!
【讨论】:
嗨,breadbin,在您的示例命名空间中,前缀为 "tem" 和 "fpm" 。我们如何在 PropertyInfo 中添加这些前缀?还是由图书馆自己处理? @silwar,请参见上面代码中的“pi.setNameSpace(QR_NAMESPACE)”行 - 这是将字符串设置为 PropertyInfo 对象的命名空间。【参考方案2】:我也遇到过类似的问题,但是我的对象实现了KvmSerializable
,并且KSoap 自动将它们序列化(它们是由wsdl2code 从WSDL 生成的)。在这种情况下,最简单的解决方案是在父级的getPropertyInfo
方法中设置PropertyInfo.namespace
,如下所示:
@Override
public void getPropertyInfo(int index, Hashtable arg1, PropertyInfo info)
switch(index)
case 0:
info.type = Person.class;
info.name = "Person";
info.namespace = "http://schemas.example.com/crm";
break;
【讨论】:
嗨..你能详细说明你做了什么并得到了解决方案。我使用上面的链接生成文件,但不知道如何使用它.. @VishwaPratap 生成的文件应包含一个带有目标服务名称的“主”文件(例如 SampleService.java)。它包含用于访问 WSDL 中定义的每个“操作”的方法。如果您对嵌套对象中缺少命名空间有疑问,您可以在我的回答中使用解决方案。比如对象关系是Project->Task->Person,可以在Task的getPropertyInfo
方法中定义Person的命名空间。
我得到了解决问题的方法,请在下面查看我的完整答案
嗨,您似乎遇到了与我在这里描述的相同的问题***.com/questions/63376212/… 我已尝试将命名空间添加到对象的字段以及对象中。你能解释一下你的解决方案吗?以上是关于Ksoap2 Android - 如何为复杂对象的子属性指定命名空间?的主要内容,如果未能解决你的问题,请参考以下文章
使用具有复杂对象的 KSoap2 调用 WCF 服务。 WCF 接收空值
如何为我在 Android 中用作背景的可绘制对象添加圆角?