kSOAP 2 Android - 将复杂类型发送到 Java Axis2 Webservice
kSOAP 2 Android - Send complex type to Java Axis2 Webservice
我编写了一个 Axis 2 Java Web 服务。在此网络服务中,有一种方法称为 "insert Entry".
从 Android 我想将我自己的对象解析到 web 服务,但是我还需要了解更多有关发送过程的信息。
网络服务方法
public int insertEntry(Object entry)
{
return 1;
}
Web 服务中的 class 正在实现可序列化
在Android中输入对象
import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.PropertyInfo;
import java.util.Hashtable;
public class Entry implements KvmSerializable {
private String destination_appliance;
private String contact;
private String card;
private String tariff;
private String tara_in;
private String reference;
public Entry(String destination_appliance, String contact, String card, String tariff, String tara_in, String reference)
{
this.destination_appliance = destination_appliance;
this.contact = contact;
this.card = card;
this.tariff = tariff;
this.tara_in = tara_in;
this.reference = reference;
}
public String getDestinationAppliance() {
return destination_appliance;
}
public void setDestinationAppliance(String destination_appliance) {
this.destination_appliance = destination_appliance;
}
public String getContact() {
return contact;
}
public void setContact(String contact) {
this.contact = contact;
}
public String getCard() {
return card;
}
public void setCard(String card) {
this.card = card;
}
public String getTariff() {
return tariff;
}
public void setTariff(String tariff) {
this.tariff = tariff;
}
public String getTaraIn() {
return tara_in;
}
public void setTaraIn(String tara_in) {
this.tara_in = tara_in;
}
public String getReference() {
return reference;
}
public void setReference(String reference) {
this.reference = reference;
}
@Override
public Object getProperty(int pid) {
switch (pid) {
case 0:
return this.destination_appliance;
case 1:
return this.contact;
case 2:
return this.card;
case 3:
return this.tariff;
case 4:
return this.tara_in;
case 5:
return this.reference;
default:
break;
}
return null;
}
@Override
public int getPropertyCount() {
return 6;
}
@Override
public void getPropertyInfo(int index, Hashtable htable, PropertyInfo info) {
switch (index) {
case 0:
info.type = PropertyInfo.STRING_CLASS;
info.name = "destination_appliance";
break;
case 1:
info.type = PropertyInfo.STRING_CLASS;
info.name = "contact";
break;
case 2:
info.type = PropertyInfo.STRING_CLASS;
info.name = "card";
break;
case 3:
info.type = PropertyInfo.STRING_CLASS;
info.name = "tariff";
break;
case 4:
info.type = PropertyInfo.STRING_CLASS;
info.name = "tara_in";
break;
case 5:
info.type = PropertyInfo.STRING_CLASS;
info.name = "reference";
break;
}
}
@Override
public String getInnerText() {
return null;
}
@Override
public void setInnerText(String s) {
}
@Override
public void setProperty(int index, Object value) {
switch (index) {
case 0:
this.destination_appliance = value.toString();
break;
case 1:
this.contact = value.toString();
break;
case 2:
this.card = value.toString();
break;
case 3:
this.tariff = value.toString();
break;
case 4:
this.tara_in = value.toString();
break;
case 5:
this.reference = value.toString();
break;
}
}
}
我的 AsyncTask 的 doBackground 方法
private class InsertEntryAsyncTask extends AsyncTask<Object, Void, Integer> {
private String resp;
private KSoapHandler kSoap = new KSoapHandler();
private static final String METHOD_NAME = "insertEntry";
private static final String SOAP_ACTION = "XXXX/" + METHOD_NAME;
@Override
protected Integer doInBackground(Object... params) {
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
SoapObject request = new SoapObject(kSoap.getNAMESPACE(), METHOD_NAME);
PropertyInfo prop = new PropertyInfo();
prop.setName("Entry");
prop.setValue(params[0]);
prop.setType(params[0].getClass());
request.addProperty(prop);
envelope.setOutputSoapObject(request);
HttpTransportSE transport = new HttpTransportSE(kSoap.getURL());
try {
transport.call(kSoap.getNAMESPACE() + kSoap.getSOAP_ACTION_PREFIX() + METHOD_NAME, envelope);
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
try {
SoapObject response = (SoapObject) envelope.getResponse();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return 1;
}
@Override
protected void onPostExecute(Integer response) {
}
}
从 AsyncTask 执行调用
Entry entry = new Entry("Test","0","0","0","Test", "Test");
InsertEntryAsyncTask asyncTaskInsertEntry = new InsertEntryAsyncTask();
asyncTaskInsertEntry.execute(entry);
请告诉我如何将条目对象发送到 Axis2 Web 服务。
这是正确的方法还是代码中存在一些错误?!
感谢您的帮助!
问候佛罗伦斯
-----更新----
好的,目前来自 Android 的请求是:
<?xml version="1.0" encoding="UTF-8"?>
<v:Envelope xmlns:v="http://schemas.xmlsoap.org/soap/envelope/" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<v:Header />
<v:Body>
<n0:insertEntry xmlns:n0="http://wmswebservice.development.ais.at" id="o0" c:root="1">
<E i:type="n0:Entry">
<destinationAppliance i:type="d:string">021</destinationAppliance>
<contact i:type="d:string">0</contact>
<card i:type="d:string">0</card>
<tariff i:type="d:string">0</tariff>
<taraIn i:type="d:string">12</taraIn>
<reference i:type="d:string">KR</reference>
</E>
</n0:insertEntry>
</v:Body>
</v:Envelope>
来自 SoapUI 的默认请求是这个 - 这非常有效 -->
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wms="http://wmswebservice.development.ais.at" xmlns:xsd="http://model.wmswebservice.development.ais.at/xsd">
<soapenv:Header/>
<soapenv:Body>
<wms:insertEntry>
<!--Optional:-->
<wms:E>
<!--Optional:-->
<xsd:card>?</xsd:card>
<!--Optional:-->
<xsd:contact>?</xsd:contact>
<!--Optional:-->
<xsd:destinationAppliance>?</xsd:destinationAppliance>
<!--Optional:-->
<xsd:reference>?</xsd:reference>
<!--Optional:-->
<xsd:taraIn>?</xsd:taraIn>
<!--Optional:-->
<xsd:tariff>?</xsd:tariff>
</wms:E>
</wms:insertEntry>
</soapenv:Body>
</soapenv:Envelope>
那么我如何使用 kSoap2 创建这样的请求? :/
您必须使用 XML 或 JSON serialize 您的对象才能发送它们。 WebService 的概念是能够与用不同语言编写的应用程序进行通信,因此该协议不知道 Java 个对象。
希望这会让您走上正确的道路。
您还没有通过 addMapping 在信封中注册您的条目。此外,您的代码工作正常。添加了映射(是的,我使用了模拟映射 asdf.com):
envelope.addMapping("http://asdf.com", "Entry", Entry.class);
它产生了漂亮的信封:
<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>
<n0:insertEntry id="o0" c:root="1" xmlns:n0="http://asdf.com">
<Entry i:type="n0:Entry">
<destination_appliance i:type="d:string">Test</destination_appliance>
<contact i:type="d:string">0</contact>
<card i:type="d:string">0</card>
<tariff i:type="d:string">0</tariff>
<tara_in i:type="d:string">Test</tara_in>
<reference i:type="d:string">Test</reference>
</Entry>
</n0:insertEntry>
</v:Body>
</v:Envelope>
有什么问题 - 我不知道它是否是您的网络服务需要的。安装 SoapUI 并尝试调用您的 WS,您将看到您需要什么。
在 transport.call 之前还添加标志 transport.debug=true,并打印到日志等请求转储 - 它可以帮助您查看内外都有什么。
好吧 - 据我所知,您添加了映射的代码应该正确调用您的 WS "on the look"。
第 2 部分
您在服务器端 WS 接口上声明为
public int insertEntry(Object entry)
{
return 1;
}
正如我在评论中提到的,您可以删除 addMapping。然后请求将不携带 i:type="n0:Entry",而是 i:type="anyType",它可能是 - WS 消耗请求。
其他:第 3 部分。
我对 Axis WS 有一点了解。我只使用 Axis 创建了客户端。但是...一般来说 - 要使用 Entry 类型 (i:type="no:Entry") 你必须将接口声明为
public int insertEntry(Entry entry)
{
return 1;
}
其中条目将在服务器端额外 class。那将是类似于您的 Android 代码中的小型 POJO:
public class Entry {
public String destination_appliance;
public String contact;
public String card;
public String tariff;
public String tara_in;
public String reference;
}
据我所知,Axis 将构建这样的 WS。但我不知道该怎么做 - 试试 uncle Google 例如 fe。 "Axis webservice complex function argument".
或者让一些 Axis 专家在这里告诉我们:)
第 4 部分。
好的,所以 - 删除 addMapping 并添加 envelope.implicitTypes=true。如果还是不行,那么(但只有这样)在 属性 条目上添加带有 setNamespace 的行。
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.implicitTypes=true;
SoapObject request = new SoapObject(kSoap.getNAMESPACE(), METHOD_NAME);
PropertyInfo prop = new PropertyInfo();
prop.setName("Entry");
prop.setValue(params[0]);
prop.setType(params[0].getClass());
prop.setNamespace(kSoap.getNAMESPACE());
request.addProperty(prop);
Here's the nested envelope
{
//<Body>
//<LTEcomCustTable123 xmlns="http://tempuri.org">
//<_accountList>
//<LTEComCustTableOut123 xmlns="http://schemas........">
//<CustAccount>1235</CustAccount>
//<DataOrigin>test</DataOrigin>
//</LTEComCustTableOut123>
//</_accountList>
//</LTEcomCustTable123>
//</Body>
Here's the code to get renter code hereid of n0 inside tag >>>
val request2 = SoapObject(NAMESPACE, METHOD_NAME)
val al = SoapObject("", METHOD_NAME1)
val tableOutbound = SoapObject("", METHOD_NAME2)
tableOutbound.addAttribute("xmlns", NAMESPACE1)
tableOutbound.addProperty("CustAccount", 13521)
tableOutbound.addProperty("DataOrigin", "Ecom")
al.addSoapObject(tableOutbound)
request2.addSoapObject(al)
val envelope = SoapSerializationEnvelope(SoapEnvelope.VER11)
envelope.setOutputSoapObject(request2)
envelope.dotNet = true
envelope.implicitTypes = true
envelope.isAddAdornments = f`enter code here`alse
envelope.bodyOut = request2
envelope.setOutputSoapObject(request2);
}
我编写了一个 Axis 2 Java Web 服务。在此网络服务中,有一种方法称为 "insert Entry".
从 Android 我想将我自己的对象解析到 web 服务,但是我还需要了解更多有关发送过程的信息。
网络服务方法
public int insertEntry(Object entry)
{
return 1;
}
Web 服务中的 class 正在实现可序列化
在Android中输入对象
import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.PropertyInfo;
import java.util.Hashtable;
public class Entry implements KvmSerializable {
private String destination_appliance;
private String contact;
private String card;
private String tariff;
private String tara_in;
private String reference;
public Entry(String destination_appliance, String contact, String card, String tariff, String tara_in, String reference)
{
this.destination_appliance = destination_appliance;
this.contact = contact;
this.card = card;
this.tariff = tariff;
this.tara_in = tara_in;
this.reference = reference;
}
public String getDestinationAppliance() {
return destination_appliance;
}
public void setDestinationAppliance(String destination_appliance) {
this.destination_appliance = destination_appliance;
}
public String getContact() {
return contact;
}
public void setContact(String contact) {
this.contact = contact;
}
public String getCard() {
return card;
}
public void setCard(String card) {
this.card = card;
}
public String getTariff() {
return tariff;
}
public void setTariff(String tariff) {
this.tariff = tariff;
}
public String getTaraIn() {
return tara_in;
}
public void setTaraIn(String tara_in) {
this.tara_in = tara_in;
}
public String getReference() {
return reference;
}
public void setReference(String reference) {
this.reference = reference;
}
@Override
public Object getProperty(int pid) {
switch (pid) {
case 0:
return this.destination_appliance;
case 1:
return this.contact;
case 2:
return this.card;
case 3:
return this.tariff;
case 4:
return this.tara_in;
case 5:
return this.reference;
default:
break;
}
return null;
}
@Override
public int getPropertyCount() {
return 6;
}
@Override
public void getPropertyInfo(int index, Hashtable htable, PropertyInfo info) {
switch (index) {
case 0:
info.type = PropertyInfo.STRING_CLASS;
info.name = "destination_appliance";
break;
case 1:
info.type = PropertyInfo.STRING_CLASS;
info.name = "contact";
break;
case 2:
info.type = PropertyInfo.STRING_CLASS;
info.name = "card";
break;
case 3:
info.type = PropertyInfo.STRING_CLASS;
info.name = "tariff";
break;
case 4:
info.type = PropertyInfo.STRING_CLASS;
info.name = "tara_in";
break;
case 5:
info.type = PropertyInfo.STRING_CLASS;
info.name = "reference";
break;
}
}
@Override
public String getInnerText() {
return null;
}
@Override
public void setInnerText(String s) {
}
@Override
public void setProperty(int index, Object value) {
switch (index) {
case 0:
this.destination_appliance = value.toString();
break;
case 1:
this.contact = value.toString();
break;
case 2:
this.card = value.toString();
break;
case 3:
this.tariff = value.toString();
break;
case 4:
this.tara_in = value.toString();
break;
case 5:
this.reference = value.toString();
break;
}
}
}
我的 AsyncTask 的 doBackground 方法
private class InsertEntryAsyncTask extends AsyncTask<Object, Void, Integer> {
private String resp;
private KSoapHandler kSoap = new KSoapHandler();
private static final String METHOD_NAME = "insertEntry";
private static final String SOAP_ACTION = "XXXX/" + METHOD_NAME;
@Override
protected Integer doInBackground(Object... params) {
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
SoapObject request = new SoapObject(kSoap.getNAMESPACE(), METHOD_NAME);
PropertyInfo prop = new PropertyInfo();
prop.setName("Entry");
prop.setValue(params[0]);
prop.setType(params[0].getClass());
request.addProperty(prop);
envelope.setOutputSoapObject(request);
HttpTransportSE transport = new HttpTransportSE(kSoap.getURL());
try {
transport.call(kSoap.getNAMESPACE() + kSoap.getSOAP_ACTION_PREFIX() + METHOD_NAME, envelope);
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
try {
SoapObject response = (SoapObject) envelope.getResponse();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return 1;
}
@Override
protected void onPostExecute(Integer response) {
}
}
从 AsyncTask 执行调用
Entry entry = new Entry("Test","0","0","0","Test", "Test");
InsertEntryAsyncTask asyncTaskInsertEntry = new InsertEntryAsyncTask();
asyncTaskInsertEntry.execute(entry);
请告诉我如何将条目对象发送到 Axis2 Web 服务。
这是正确的方法还是代码中存在一些错误?!
感谢您的帮助!
问候佛罗伦斯
-----更新----
好的,目前来自 Android 的请求是:
<?xml version="1.0" encoding="UTF-8"?>
<v:Envelope xmlns:v="http://schemas.xmlsoap.org/soap/envelope/" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<v:Header />
<v:Body>
<n0:insertEntry xmlns:n0="http://wmswebservice.development.ais.at" id="o0" c:root="1">
<E i:type="n0:Entry">
<destinationAppliance i:type="d:string">021</destinationAppliance>
<contact i:type="d:string">0</contact>
<card i:type="d:string">0</card>
<tariff i:type="d:string">0</tariff>
<taraIn i:type="d:string">12</taraIn>
<reference i:type="d:string">KR</reference>
</E>
</n0:insertEntry>
</v:Body>
</v:Envelope>
来自 SoapUI 的默认请求是这个 - 这非常有效 -->
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wms="http://wmswebservice.development.ais.at" xmlns:xsd="http://model.wmswebservice.development.ais.at/xsd">
<soapenv:Header/>
<soapenv:Body>
<wms:insertEntry>
<!--Optional:-->
<wms:E>
<!--Optional:-->
<xsd:card>?</xsd:card>
<!--Optional:-->
<xsd:contact>?</xsd:contact>
<!--Optional:-->
<xsd:destinationAppliance>?</xsd:destinationAppliance>
<!--Optional:-->
<xsd:reference>?</xsd:reference>
<!--Optional:-->
<xsd:taraIn>?</xsd:taraIn>
<!--Optional:-->
<xsd:tariff>?</xsd:tariff>
</wms:E>
</wms:insertEntry>
</soapenv:Body>
</soapenv:Envelope>
那么我如何使用 kSoap2 创建这样的请求? :/
您必须使用 XML 或 JSON serialize 您的对象才能发送它们。 WebService 的概念是能够与用不同语言编写的应用程序进行通信,因此该协议不知道 Java 个对象。
希望这会让您走上正确的道路。
您还没有通过 addMapping 在信封中注册您的条目。此外,您的代码工作正常。添加了映射(是的,我使用了模拟映射 asdf.com):
envelope.addMapping("http://asdf.com", "Entry", Entry.class);
它产生了漂亮的信封:
<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>
<n0:insertEntry id="o0" c:root="1" xmlns:n0="http://asdf.com">
<Entry i:type="n0:Entry">
<destination_appliance i:type="d:string">Test</destination_appliance>
<contact i:type="d:string">0</contact>
<card i:type="d:string">0</card>
<tariff i:type="d:string">0</tariff>
<tara_in i:type="d:string">Test</tara_in>
<reference i:type="d:string">Test</reference>
</Entry>
</n0:insertEntry>
</v:Body>
</v:Envelope>
有什么问题 - 我不知道它是否是您的网络服务需要的。安装 SoapUI 并尝试调用您的 WS,您将看到您需要什么。 在 transport.call 之前还添加标志 transport.debug=true,并打印到日志等请求转储 - 它可以帮助您查看内外都有什么。
好吧 - 据我所知,您添加了映射的代码应该正确调用您的 WS "on the look"。
第 2 部分
您在服务器端 WS 接口上声明为
public int insertEntry(Object entry)
{
return 1;
}
正如我在评论中提到的,您可以删除 addMapping。然后请求将不携带 i:type="n0:Entry",而是 i:type="anyType",它可能是 - WS 消耗请求。
其他:第 3 部分。
我对 Axis WS 有一点了解。我只使用 Axis 创建了客户端。但是...一般来说 - 要使用 Entry 类型 (i:type="no:Entry") 你必须将接口声明为
public int insertEntry(Entry entry)
{
return 1;
}
其中条目将在服务器端额外 class。那将是类似于您的 Android 代码中的小型 POJO:
public class Entry {
public String destination_appliance;
public String contact;
public String card;
public String tariff;
public String tara_in;
public String reference;
}
据我所知,Axis 将构建这样的 WS。但我不知道该怎么做 - 试试 uncle Google 例如 fe。 "Axis webservice complex function argument".
或者让一些 Axis 专家在这里告诉我们:)
第 4 部分。
好的,所以 - 删除 addMapping 并添加 envelope.implicitTypes=true。如果还是不行,那么(但只有这样)在 属性 条目上添加带有 setNamespace 的行。
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.implicitTypes=true;
SoapObject request = new SoapObject(kSoap.getNAMESPACE(), METHOD_NAME);
PropertyInfo prop = new PropertyInfo();
prop.setName("Entry");
prop.setValue(params[0]);
prop.setType(params[0].getClass());
prop.setNamespace(kSoap.getNAMESPACE());
request.addProperty(prop);
Here's the nested envelope
{
//<Body>
//<LTEcomCustTable123 xmlns="http://tempuri.org">
//<_accountList>
//<LTEComCustTableOut123 xmlns="http://schemas........">
//<CustAccount>1235</CustAccount>
//<DataOrigin>test</DataOrigin>
//</LTEComCustTableOut123>
//</_accountList>
//</LTEcomCustTable123>
//</Body>
Here's the code to get renter code hereid of n0 inside tag >>>
val request2 = SoapObject(NAMESPACE, METHOD_NAME)
val al = SoapObject("", METHOD_NAME1)
val tableOutbound = SoapObject("", METHOD_NAME2)
tableOutbound.addAttribute("xmlns", NAMESPACE1)
tableOutbound.addProperty("CustAccount", 13521)
tableOutbound.addProperty("DataOrigin", "Ecom")
al.addSoapObject(tableOutbound)
request2.addSoapObject(al)
val envelope = SoapSerializationEnvelope(SoapEnvelope.VER11)
envelope.setOutputSoapObject(request2)
envelope.dotNet = true
envelope.implicitTypes = true
envelope.isAddAdornments = f`enter code here`alse
envelope.bodyOut = request2
envelope.setOutputSoapObject(request2);
}