You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin用ksoap2调用WebService遇SoapFault错误求助

解决ksoap2调用WebService时的SoapFault(soap:Client/Unmarshalling Error)问题

从你给出的错误信息Unmarshalling Error: unexpected element (uri:"http://soapservicetest/", local:"input"). Expected elements are <{}input>,可以明确问题出在元素命名空间不匹配:你的Android客户端发送的<input>元素带有http://soapservicetest/命名空间,但服务端期望的是不带任何命名空间的<input>元素(<{}input>里的{}代表空命名空间)。

具体修改方案

看你的代码,创建SoapObject时使用了NAMESPACE = "http://soapservicetest/",ksoap2默认会把添加到SoapObject中的PropertyInfo元素自动关联这个命名空间。你需要手动给input属性设置空命名空间,修正代码如下:

fun getResultFromInput(input: Int?){ 
    val request = SoapObject(NAMESPACE, METHOD_NAME) 
    val celsiusPI = PropertyInfo() 
    celsiusPI.setName("input") 
    celsiusPI.value = input 
    // 关键:设置空命名空间,让input元素不带命名空间
    celsiusPI.namespace = ""
    // 注意:如果服务端期望的是Int类型,这里应该用Int而不是Double
    celsiusPI.setType(Int::class.javaPrimitiveType) 
    request.addProperty(celsiusPI) 

    val envelope = SoapSerializationEnvelope(SoapEnvelope.VER11) 
    envelope.env = "http://schemas.xmlsoap.org/soap/envelope/" 
    envelope.bodyOut = request 
    envelope.encodingStyle = SoapSerializationEnvelope.ENC2003 
    // 重要:如果你的服务不是.NET开发的(W3School的原服务不是),建议把dotNet设为false
    envelope.dotNet = false 
    envelope.setOutputSoapObject(request) 

    val androidHttpTransport = HttpTransportSE(URL) 
    try { 
        androidHttpTransport.call(SOAP_ACTION, envelope) 
        // 这里修正:应该从envelope获取响应,而不是未定义的responseLocal
        val response = envelope.response.toString() 
        // 处理响应逻辑...
    } catch (e: Exception){ 
        e.printStackTrace() 
    } catch (t: SocketTimeoutException) { 
        t.printStackTrace(); 
    } catch (i: IOException) { 
        i.printStackTrace(); 
    } 
}

额外注意点

  1. 类型匹配:你传入的参数是Int?,但代码里设置的类型是Double::class.javaPrimitiveType,如果服务端接口定义的是整数类型,这里会导致类型不匹配,建议改成Int::class.javaPrimitiveType。
  2. dotNet属性:envelope.dotNet = true是针对.NET开发的WebService的适配,W3School的温度转换服务是基于非.NET技术的,设置为false更合理,避免不必要的命名空间或格式差异。
  3. 响应获取:你代码里的response = responseLocal.toString()有问题,responseLocal未定义,正确的方式是从envelope.response获取服务端返回的SoapObject或直接转成字符串。

验证步骤

修改后重新调用,你可以通过抓包工具查看发送的SOAP请求体,确认<input>元素不再带有http://soapservicetest/命名空间,格式应该类似:

<input>xxx</input>

而不是:

<input xmlns="http://soapservicetest/">xxx</input>

内容的提问来源于stack exchange,提问作者Fab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:07:08