当我尝试调用托管的wsdl描述的Web服务时,我收到以下错误。
"Unable to un-marshall between the XML Document and JAXB Objects."
'org.xml.sax.SAXException: Unable to un-marshall between the XML Document and JAXB Objects. See server logs for more details.
null' faultactor: 'null' detail: org.kxml2.kdom.Node@6782a9
at org.ksoap2.serialization.SoapSerializationEnvelope.parseBody(SoapSerializationEnvelope.java:137)
at org.ksoap2.SoapEnvelope.parse(SoapEnvelope.java:140)
at org.ksoap2.transport.Transport.parseResponse(Transport.java:129)
at org.ksoap2.transport.HttpTransportSE.parseResponse(HttpTransportSE.java:301)
at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:274)
其实我在JAVA程序中测试ksoap库而不是android。 一旦此测试通过,我计划将代码迁移到Android。 但是由于在非编组期间发生了错误,我假设正在进行服务调用,并且解析响应时存在问题。
以下是我正在测试的Java程序:
package com.tc.wsdl.runner;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpResponseException;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;
import com.tc.ws.client.session.InternalServerException;
import com.tc.ws.client.session.InternalServerFaultFault;
import com.tc.ws.client.session.InvalidUserFaultFault;
public class TestRunner {
/**
* @param args
*/
public static void main(String[] args)
{
// TODO Auto-generated method stub
try
{
ksoapGetAvailableServices();
}
catch(Exception e)
{
e.printStackTrace();
}
}
private static void ksoapGetAvailableServices()
throws HttpResponseException, IOException, XmlPullParserException {
String NAMESPACE = "http://somename.com/Services/Core/2006-03";
String METHOD_NAME = "getAvailableServices";
String URL="http://some.com:8080/tc/services/Core-2006-03-Session?wsdl";
String SOAP_ACTION_PREFIX="/";
GetAvailableServicesInput input = new GetAvailableServicesInput();
PropertyInfo propInfo = new PropertyInfo();
propInfo.name = "getAvailableServicesRequest";
propInfo.setValue(input);
propInfo.type = GetAvailableServicesInput.class;
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty(propInfo);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
envelope.implicitTypes = true;
envelope.setOutputSoapObject(request);
envelope.addMapping("http://somename.com/Schemas/Core/2006-03/Session", "GetAvailableServicesInput",new GetAvailableServicesInput ().getClass());
envelope.addMapping("http://somename.com/Schemas/Core/2006-03/Session", "GetAvailableServicesResponse",new GetAvailableServicesResponse ().getClass());
envelope.addMapping("http://somename.com/Schemas/Soa/2006-03/Exceptions", "InvalidUserFault",new InvalidUserFaultFault ().getClass());
envelope.addMapping("http://somename.com/Schemas/Soa/2006-03/Exceptions", "InternalServerFault",new InternalServerFaultFault ().getClass());
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.debug = true;
androidHttpTransport.call(NAMESPACE + SOAP_ACTION_PREFIX + METHOD_NAME,
envelope);
GetAvailableServicesResponse resultsRequestSOAP = (GetAvailableServicesResponse) envelope
.getResponse();
System.out.println("********" + resultsRequestSOAP);
}
static class GetAvailableServicesInput implements KvmSerializable
{
@Override
public String getInnerText() {
// TODO Auto-generated method stub
return null;
}
@Override
public Object getProperty(int arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public int getPropertyCount() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo arg2) {
// TODO Auto-generated method stub
}
@Override
public void setInnerText(String arg0) {
// TODO Auto-generated method stub
}
@Override
public void setProperty(int arg0, Object arg1) {
// TODO Auto-generated method stub
}
}
static class GetAvailableServicesResponse implements KvmSerializable
{
protected ArrayList<String> serviceNames;
@Override
public String getInnerText() {
// TODO Auto-generated method stub
return null;
}
@Override
public Object getProperty(int index) {
// TODO Auto-generated method stub
switch (index){
case 0:
return serviceNames;
default:
return null;
}
}
@Override
public int getPropertyCount() {
// TODO Auto-generated method stub
return 1;
}
@Override
public void getPropertyInfo(int index, Hashtable arg1, PropertyInfo info) {
// TODO Auto-generated method stub
switch (index)
{
case 0:
info.type = PropertyInfo.VECTOR_CLASS;
info.name = "serviceNames";
break;
default:
break;
}
}
@Override
public void setInnerText(String arg0) {
// TODO Auto-generated method stub
}
@Override
public void setProperty(int index, Object arg1) {
// TODO Auto-generated method stub
switch (index){
case 0:
serviceNames = (ArrayList<String>) arg1;
break;
default:
break;
}
}
public ArrayList<String> getServiceNames() {
if (serviceNames == null) {
serviceNames = new ArrayList<String>();
}
return this.serviceNames;
}
public void setServiceNames(ArrayList<String> serviceNames) {
this.serviceNames = serviceNames;
}
}
}
以下是剥离的WSDL。我保留了与服务操作相关的部分 - getAvailableServices - 我在下面的wsdl中调用:
<wsdl:definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:imp0="http://somename.com/Schemas/Soa/2006-03/Base"
xmlns:imp1="http://somename.com/Schemas/Soa/2006-03/Exceptions" xmlns:imp2="http://somename.com/Schemas/Core/2006-03/Session"
xmlns:imp3="http://somename.com/webservices/2005-06/schemas/WSFaults" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://somename.com/Services/Core/2006-03" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsi="http://ws-
i.org/schemas/conformanceClaim/" xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://somename.com/Services/Core/2006-03">
<wsdl:types>
<xs:schema>
<xs:import namespace="http://somename.com/Schemas/Soa/2006-03/Base" schemaLocation="../schemas/SoaBase.xsd"/>
<xs:import namespace="http://somename.com/Schemas/Soa/2006-03/Exceptions" schemaLocation="../schemas/SoaExceptions.xsd"/>
<xs:import namespace="http://somename.com/Schemas/Core/2006-03/Session" schemaLocation="../schemas/Core0603Session.xsd"/>
<xs:import namespace="http://somename.com/webservices/2005-06/schemas/WSFaults" schemaLocation="../schemas/WSFaults.xsd"/>
</xs:schema>
</wsdl:types>
<wsdl:message name="InternalServerFaultFault">
<wsdl:part element="imp1:InternalServerFault" name="exx01"/>
</wsdl:message>
<wsdl:message name="InvalidCredentialsFaultFault">
<wsdl:part element="imp1:InvalidCredentialsFault" name="exx02"/>
</wsdl:message>
<wsdl:message name="ServiceFaultFault">
<wsdl:part element="imp1:ServiceFault" name="exx01"/>
</wsdl:message>
<wsdl:message name="InvalidUserFaultFault">
<wsdl:part element="imp1:InvalidUserFault" name="exx02"/>
</wsdl:message>
<wsdl:message name="getAvailableServicesRequest">
<wsdl:part element="imp2:GetAvailableServicesInput" name="in0"/>
</wsdl:message>
<wsdl:message name="getAvailableServicesResponse">
<wsdl:part element="imp2:GetAvailableServicesResponse" name="out"/>
</wsdl:message>
<wsdl:portType name="Core0603Session">
<wsdl:operation name="getAvailableServices">
<wsdl:documentation>
<![CDATA[
This will return a list of services that this server instance supports.
]]>
</wsdl:documentation>
<wsdl:input message="tns:getAvailableServicesRequest" name="getAvailableServicesRequest"/>
<wsdl:output message="tns:getAvailableServicesResponse" name="getAvailableServicesResponse"/>
<wsdl:fault message="tns:InternalServerFaultFault" name="InternalServerFaultError"/>
<wsdl:fault message="tns:InvalidUserFaultFault" name="InvalidUserFaultError"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="Core0603SessionSoapBinding" type="tns:Core0603Session">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getAvailableServices">
<soap:operation soapAction="getAvailableServices" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="InternalServerFaultError">
<soap:fault name="InternalServerFaultError" use="literal"/>
</wsdl:fault>
<wsdl:fault name="InvalidUserFaultError">
<soap:fault name="InvalidUserFaultError" use="literal"/>
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="Core0603SessionService">
<wsdl:port binding="tns:Core0603SessionSoapBinding" name="Core-2006-03-Session">
<soap:address location="http://somewhere.com:8080/app/services/Core-2006-03-Session"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
请帮助我找出错误。
GetAvailableServicesResponse类与通过wsimport生成的类相似。但是我希望这在Android中工作,所以我在类路径中避免除了ksoap-with-dependencies jar之外的所有外部库。因此响应对象包含一个String列表。
我在代码中也添加了名称空间映射。 我尝试了名称空间xmlns:tns和xmlns:imp2。在解析响应时仍然得到相同的Un-marhsall错误。有没有办法获取ksoap库试图解析的响应XML?
答案 0 :(得分:1)
您需要映射新的KVSerializabel类,请使用:
envelope.setOutputSoapObject(request);
envelope.addMapping(NAMESPACE, "YourObjectOnWebServices",new GetAvailableServicesInput ().getClass());
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);