【问题标题】:KSOAP2 for Android gives适用于 Android 的 KSOAP2 提供
【发布时间】:2010-12-29 19:30:16
【问题描述】:

我正在尝试访问其 WSDL 位于 http://srilanka.lk:9080/services/CropServiceProxy?wsdl 的 Web 服务。使用 SoapUI 我发送了一个请求并成功获得了响应。

然后使用 KSoap2 for Android 我试图得到响应。但我得到的只是一个 SoapFault 错误。代码如下。

String NAMESPACE = "http://schemas.icta.lk/xsd/crop/handler/v1";

    String URL = "http://www.srilanka.lk:9080/services/CropServiceProxy.CropServiceProxyHttpSoap12Endpoint";

    String method_name = "getCropDataList";
    String SOAP_ACTION = method_name;

    SoapObject request = new SoapObject(NAMESPACE, method_name);
    String crop_code_str = String.valueOf(code.getText().toString());
    System.out.println(crop_code_str);
    System.out.println(request.toString());
    request.addProperty("code", crop_code_str );
    System.out.println(request.getProperty("code").toString());

    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER12);
    envelope.setOutputSoapObject(request);

    System.out.println("body out : " + envelope.bodyOut.toString());

    HttpTransportSE http_transport  = new HttpTransportSE(URL);
    try {
        http_transport.call(SOAP_ACTION, envelope);
        System.out.println(envelope.bodyIn.toString());

    } catch (Exception e) {
        e.printStackTrace();
        answer.setText("error caught");
    }

这会导致以下结果。

W/System.err(  394): org.xmlpull.v1.XmlPullParserException: expected: START_TAG {http://www.w3.org/2001/12/soap-envelope}Envelope (position:START_TAG <{http://schemas.xmlsoap.org/soap/envelope/}soapenv:Envelope>@1:114 in java.io.InputStreamReader@43e81258)  

我尝试使用 VER11,但它在 bodyIn 中出现以下错误。

I/System.out(  365): SoapFault - faultcode: 'soapenv:Server' faultstring: 'org.apache.axis2.databinding.ADBException: Unexpected subelement code' faultactor: 'null' detail: org.kxml2.kdom.Node@43e84648

Ksoap2 for android 有什么问题吗?那么还有另一种方式可以在 Android 中使用 Web 服务吗? (只有 SOAP 可用)

更新:我尝试了复杂类型的 KvmSerializable 接口。以下是我的代码。我仍然得到同样的错误。在 http_transport.call 行中抛出 XMLPullParser 错误。

这是客户端的复杂类型实现。我只有 WSDL。

public class CropInfo implements KvmSerializable {

    private String name;
    private float price;
    private String location;

    @Override
    public Object getProperty(int arg0) {
        switch (arg0){
        case 0:
            return name;
        case 1:
            return price;
        case 2:
            return location;
        default:
                return null;
        }
    }

    @Override
    public int getPropertyCount() {
        return 3;
    }

    @Override
    public void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo arg2) {
        switch (arg0){
        case 0:
            arg2.type = PropertyInfo.STRING_CLASS;
            arg2.name = "Name";
            break;
        case 1:
            arg2.type = Float.class;
            arg2.name = "Price";
            break;
        case 2:
            arg2.type = PropertyInfo.STRING_CLASS;
            arg2.name = "Location";
            break;
        default:
                break;
        }

    }

    @Override
    public void setProperty(int arg0, Object arg1) {
        switch(arg0){
        case 0:
            name = arg1.toString();
            break;
        case 1:
            price = Float.parseFloat(arg1.toString());
        case 2:
            location = arg1.toString();
        default:
            break;
        }
    }
}

用于访问和解析 Web 服务响应的修改代码。

String NAMESPACE = "http://schemas.icta.lk/xsd/crop/handler/v1/"; 字符串 URL = "http://www.srilanka.lk:9080/services/CropServiceProxy.CropServiceProxyHttpSoap12Endpoint"; String method_name = "getCropDataList"; String SOAP_ACTION = "http://schemas.icta.lk/xsd/crop/handler/v1/getCropDataList";

    SoapObject soap_request = new SoapObject(NAMESPACE, method_name);
    String crop_code_str = String.valueOf(code.getText().toString());
    System.out.println(crop_code_str);
    System.out.println(soap_request.toString());
    soap_request.addProperty("code", crop_code_str );
    System.out.println(soap_request.getProperty("code").toString());

    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER12);
    envelope.setOutputSoapObject(soap_request);
    envelope.addMapping(NAMESPACE, "cropInfo", CropInfo.class);
    //envelope.dotNet=true;

    Marshal floatMarshal = new MarshalFloat();
    floatMarshal.register(envelope);

    System.out.println("body out : " + envelope.bodyOut.toString());

    //AndroidHttpTransport http_transport = new AndroidHttpTransport(URL);
    HttpTransportSE http_transport  = new HttpTransportSE(URL);
    try {
                //error comes from this call            
                http_transport.call(SOAP_ACTION, envelope);


        Vector<CropInfo> result_array = (Vector<CropInfo>)envelope.getResponse();
        if(result_array != null){
            for (CropInfo current_crop: result_array){
                System.out.println(current_crop.getName());
                System.out.println(Float.toString(current_crop.getPrice()));
            }
        }

    } catch (Exception e) {
        e.printStackTrace();
        answer.setText("error caught");
    }

【问题讨论】:

  • 我收到一个肥皂响应 VersionMismatch系统仅支持 SOAP 1.1 或 SOAP 1.2 消息。这就是发生 XML 错误的原因。但我使用的是 VER12,因为 SoapUI 说该服务是soap 1.2
  • 当我使用 VER11 时,我得到“org.apache.axis2.databinding.ADBException: Unexpected subelement code”作为响应。
  • soap1.2 支持仅在最新版本中变得更好。特别是对 1.2 的适当的 SoapFault 支持。确保使用最新版本 - 来自code.google.com/p/ksoap2-android/wiki/HowToUse?tm=2的 2.5.8
  • 你好Manfred,后来发现他们最后暴露的服务有问题。他们最终给出了一个更容易处理的带有 JSON 的 REST 接口。
  • 也许你应该关闭或删除问题

标签: android web-services soap soapui ksoap2


【解决方案1】:

我已经阅读了很多关于使用 KSoap 的痛苦和不一致的帖子。您可以使用 DefaultHttpClient 类进行 http 发布,然后手动创建 SOAP 标头并解析响应。

【讨论】:

  • 我现在正在尝试这样做。但是我在服务端点上得到了 FileNotFoundException。我已将 URL 设置为上面提到的端点 12 (srilanka.lk:9080/services/…)。它不是正确的 URL 还是应该是 wsdl URL?我正在使用 HttpURLConnection。
  • 这绝对是要走的路。过去几天我一直在努力让 ksoap 工作,我只是使用 Postman 在不到 5 分钟的时间内复制了调用。
【解决方案2】:

我认为你的代码没问题。

渴望看看你的 wsdl 文件,在这里你可以找到你需要的所有数据,比如 namspace、action 等等。在很多情况下,action 是一个像“”这样的空字符串。 我总是选择 SoapEnvelope.VER11,但通常没关系。 此代码仅适用于原始数据类型和字符串数组,如果您需要复杂数据,则必须实现 kvmSerializable 接口。

对不起,我的英语不好,我希望你明白我的意思。下面是一个有用的链接。

http://www.drdobbs.com/mobility/208800166;jsessionid=2VAK4K4QQ5H3TQE1GHPSKH4ATMY32JVN?pgno=1

【讨论】:

  • 嗨 lx_man,感谢您的提示。我使用了 KvmSerializable 并实现了复杂类型。但我最终还是得到了错误。我已经用最新的代码更新了问题。
  • 你可以看看wsdltoksoap.googlecode.com,它是一个Android兼容的Java Webservice客户端代码生成器
【解决方案3】:

KSoap 确实倾向于将自己的命名空间插入到每个标签中,这可以给出输出 你可以试试

envelope.implicitTypes = true;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-02
    • 1970-01-01
    相关资源
    最近更新 更多