【问题标题】:kSOAP 2 Android - Send complex type to Java Axis2 WebservicekSOAP 2 Android - 将复杂类型发送到 Java Axis2 Webservice
【发布时间】:2015-03-28 13:42:47
【问题描述】:

我编写了一个 Axis 2 Java Web 服务。在这个网络服务中,有一种方法叫做“插入条目”。

我想从 Android 解析我自己的对象到 web 服务,但是关于发送过程,我还需要了解更多。

网络服务方法

public int insertEntry(Object entry)
{
    return 1;
}

来自 web 服务的类正在实现可序列化

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 创建这样的请求? :/

【问题讨论】:

  • 非常非常漂亮的代码演示。喜欢你编写代码的方式。

标签: android axis2 android-ksoap2


【解决方案1】:
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);

}

【讨论】:

    【解决方案2】:

    您尚未通过 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 并尝试调用 Your WS,您将看到您需要什么。 在 transport.call 之前添加标志 transport.debug=true,并打印到日志等请求转储 - 它可以帮助您查看您的输出和输入。

    好吧 - 您添加了映射的代码应该对您的 WS 进行正确调用,就我可能认为“外观”而言。

    第 2 部分

    您在服务器端 WS 接口上声明为

    public int insertEntry(Object entry)
    {
        return 1;
    }
    

    正如我在 cmets 中提到的,您可以删除 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;
    }
    

    其中 Entry 将是服务器端的附加类。这将是类似于您的 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。但是我不知道该怎么做——试试谷歌叔叔的例子。 《Axis webservice 复杂函数参数》。

    或者也许让一些 Axis 专业人士在这里告诉我们:)

    第 4 部分。

    好的,所以 - 删除 addMapping 并添加信封.implicitTypes=true。如果仍然不行,那么(但只有这样)在属性 Entry 上添加带有 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);
    

    【讨论】:

    • 你好 mmprog!谢谢你的帮助。我添加了映射,现在我得到以下 BodyIn :/ SoapFault - faultcode: 'soapenv:Server' faultstring: 'Unknow type {NAMESPACE}Entry' faultactor: 'null' detail: org.kxml2.kdom.Node@19e778da 就是这样因为我在 web 服务中有这个方法: public int insertEntry(Object entry) { return 1;参数对象是否为假?请帮我将入口对象传递给 Axis2 Webservice .. BR
    • 我认为我的网络服务不知道类型 Entry :/
    • 我不太清楚如何定义轴的条目。您应该在 WS 端声明这样的类并将方法声明为 insertEntry(Entry entry) 但我无法帮助您如何正确地做到这一点。您也可以尝试(原文如此!)删除带有映射的行,然后它将被视为“anyType”-可能是 WS 将其视为“对象”。
    • 无论如何,学习如何在轴端定义条目 - 您必须以某种方式将数据映射到模型。像 Object 这样的通用类型对于长距离编码来说并不是一件好事;)
    • 好的,谢谢,那么传输数据的正确方法是什么。一个String,然后分割数据,或者你说的点长距离编码和对象不是很好
    【解决方案3】:

    您必须使用 XML 或 JSON serialize 您的对象才能发送它们。 WebService 的概念是能够与用不同语言编写的应用程序进行通信,因此协议不知道 Java 对象。

    希望这会让你走上正确的道路。

    【讨论】:

    • 感谢您的回答。但是这种方式的教程很多。执行正确发送过程的正确任务是什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-06
    • 2011-01-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多