Reputation: 1046
I am getting the following error when I try to call a web service described by a hosted wsdl.
"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)
Actually I am testing the ksoap library in a JAVA program and not android. Once this test passes I am planning to migrate the code to Android. But since the error is occurring during un-marshalling, I assume the service call is happening and there is an issue with parsing the response.
Below is my Java program I am testing with:
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;
}
}
}
Below is the stripped out WSDL. I have kept the parts related to the service operation - getAvailableServices - I am calling in the below 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>
Kindly help in identifying the mistake I have made.
The GetAvailableServicesResponse class is similar to the one generated through wsimport. But I want this to work in Android so I am avoiding all external libraries except ksoap-with-dependencies jar in classpath. So the response object contains a list of String.
I have added the namespace mapping also as updated in the code. I tried both the namespaces xmlns:tns and xmlns:imp2. Still getting the same Un-marhsall error while parsing the response. Is there a way to get the response XML that the ksoap library is trying to parse?
Upvotes: 0
Views: 1004
Reputation: 11
You need map your new KVSerializabel class, use this:
envelope.setOutputSoapObject(request);
envelope.addMapping(NAMESPACE, "YourObjectOnWebServices",new GetAvailableServicesInput ().getClass());
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
Upvotes: 1