KSoap2 and KvmSerializable - How to send complex objects like Stringarrays

I want to send a complex object from my Ksoap client to my web service. This is an object of my category. The code is based on the example of this tutorial:

http://seesharpgears.blogspot.de/2010/10/ksoap-android-web-service-tutorial-with.html

The web service is running and the WSDL file shows the category object. But if I send a category object to my soap webservice, the following error will appear:

[ERROR] An exception occurred while trying to call the service method getCategoryObject org.apache.axis2.AxisFault: type Unknow {http://ws.chathura.com} The Logcat category shows the following: 06-12 11: 08: 57.576: W / System. err (777): SoapFault - error code: 'soapenv: server error: "Unknow type {http://ws.chathura.com} Category' faultactor: 'null': org.kxml2.kdom.Node@4054a528

This is my launch of the Java Webservice on Tomcat 7:

package com.chathura.ws; import java.util.Vector; public class HelloWorldWS { public Category getCategoryObject(Category obj) { Category C1 = new Category(); C1.setCategoryId(1); C1.setDescription("server desc"); C1.setName("server Name"); System.out.println(obj.getCategoryId()); return C1; } } 

This is my category class on WebServer:

 package com.chathura.ws; public class Category { private int CategoryId; private String Name; private String Description; /** * @return the categoryId */ public int getCategoryId() { return CategoryId; } /** * @param categoryId the categoryId to set */ public void setCategoryId(int categoryId) { CategoryId = categoryId; } /** * @return the name */ public String getName() { return Name; } /** * @param name the name to set */ public void setName(String name) { Name = name; } /** * @return the description */ public String getDescription() { return Description; } /** * @param description the description to set */ public void setDescription(String description) { Description = description; } } 

This is the WSDL file:

  This XML file does not appear to have any style information associated with it. The document tree is shown below. <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:ns1="http://org.apache.axis2/xsd" xmlns:ns="http://ws.chathura.com" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:ax21="http://ws.chathura.com/xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" targetNamespace="http://ws.chathura.com"> <wsdl:documentation>Please Type your service description here</wsdl:documentation> <wsdl:types> <xs:schema attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://ws.chathura.com/xsd"> <xs:complexType name="Category"> <xs:sequence> <xs:element minOccurs="0" name="categoryId" type="xs:int"/> <xs:element minOccurs="0" name="description" nillable="true" type="xs:string"/> <xs:element minOccurs="0" name="name" nillable="true" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:schema> <xs:schema xmlns:ax22="http://ws.chathura.com/xsd" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://ws.chathura.com"> <xs:import namespace="http://ws.chathura.com/xsd"/> <xs:element name="getCategoryObject"> <xs:complexType> <xs:sequence> <xs:element minOccurs="0" name="obj" nillable="true" type="ax21:Category"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="getCategoryObjectResponse"> <xs:complexType> <xs:sequence> <xs:element minOccurs="0" name="return" nillable="true" type="ax21:Category"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> </wsdl:types> <wsdl:message name="getCategoryObjectRequest"> <wsdl:part name="parameters" element="ns:getCategoryObject"/> </wsdl:message> <wsdl:message name="getCategoryObjectResponse"> <wsdl:part name="parameters" element="ns:getCategoryObjectResponse"/> </wsdl:message> <wsdl:portType name="HelloWorldWSPortType"> <wsdl:operation name="getCategoryObject"> <wsdl:input message="ns:getCategoryObjectRequest" wsaw:Action="urn:getCategoryObject"/> <wsdl:output message="ns:getCategoryObjectResponse" wsaw:Action="urn:getCategoryObjectResponse"/> </wsdl:operation> </wsdl:portType> <wsdl:binding name="HelloWorldWSSoap11Binding" type="ns:HelloWorldWSPortType"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> <wsdl:operation name="getCategoryObject"> <soap:operation soapAction="urn:getCategoryObject" style="document"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:binding name="HelloWorldWSSoap12Binding" type="ns:HelloWorldWSPortType"> <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> <wsdl:operation name="getCategoryObject"> <soap12:operation soapAction="urn:getCategoryObject" style="document"/> <wsdl:input> <soap12:body use="literal"/> </wsdl:input> <wsdl:output> <soap12:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:binding name="HelloWorldWSHttpBinding" type="ns:HelloWorldWSPortType"> <http:binding verb="POST"/> <wsdl:operation name="getCategoryObject"> <http:operation location="getCategoryObject"/> <wsdl:input> <mime:content type="text/xml" part="parameters"/> </wsdl:input> <wsdl:output> <mime:content type="text/xml" part="parameters"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="HelloWorldWS"> <wsdl:port name="HelloWorldWSHttpSoap11Endpoint" binding="ns:HelloWorldWSSoap11Binding"> <soap:address location="http://localhost:8080/WebProject_KomplexObjects/services/HelloWorldWS.HelloWorldWSHttpSoap11Endpoint/"/> </wsdl:port> <wsdl:port name="HelloWorldWSHttpSoap12Endpoint" binding="ns:HelloWorldWSSoap12Binding"> <soap12:address location="http://localhost:8080/WebProject_KomplexObjects/services/HelloWorldWS.HelloWorldWSHttpSoap12Endpoint/"/> </wsdl:port> <wsdl:port name="HelloWorldWSHttpEndpoint" binding="ns:HelloWorldWSHttpBinding"> <http:address location="http://localhost:8080/WebProject_KomplexObjects/services/HelloWorldWS.HelloWorldWSHttpEndpoint/"/> </wsdl:port> </wsdl:service> </wsdl:definitions> 

And this is my Android testing app:

  package de.bachelor.marcel; import java.util.Vector; import org.ksoap2.SoapEnvelope; import org.ksoap2.serialization.PropertyInfo; import org.ksoap2.serialization.SoapObject; import org.ksoap2.serialization.SoapSerializationEnvelope; import org.ksoap2.transport.AndroidHttpTransport; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class WSClientKomplexeObjekteActivity extends Activity { private static final String SOAP_ACTION = "http://ws.chathura.com/getCategoryObject"; private static final String METHOD_NAME = "getCategoryObject"; private static final String NAMESPACE = "http://ws.chathura.com"; private static final String URL = "http://192.168.2.102:8080/WebProject_KomplexObjects/services/HelloWorldWS?wsdl"; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME); /* * Create Category with Id to be passed as an argument * * */ Category C = new Category(); C.CategoryId = 1; C.Description = "Das ist die Beschreibung"; C.Name = "ObjektName"; /* * Set the category to be the argument of the web service method * * */ PropertyInfo objekt = new PropertyInfo(); objekt.setName("obj"); objekt.setValue(C); objekt.setType(C.getClass()); Request.addProperty(objekt); /* * Set the web service envelope * * */ SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.setOutputSoapObject(Request); envelope.addMapping(NAMESPACE, "Category",new Category().getClass()); AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(URL); /* * Call the web service and retrieve result ... how luvly <3 * * */ try { androidHttpTransport.call(SOAP_ACTION, envelope); SoapObject response = (SoapObject)envelope.getResponse(); C.CategoryId = Integer.parseInt(response.getProperty(0).toString()); C.Name = response.getProperty(1).toString(); C.Description = (String) response.getProperty(2).toString(); TextView tv = (TextView)findViewById(R.id.textview1); tv.setText("CategoryId: " +C.CategoryId + " Name: " + C.Name + " Description " + C.Description); } catch(Exception e) { e.printStackTrace(); } } } 

And here is the category class from Android Client:

 package de.bachelor.marcel; import java.util.Hashtable; import org.ksoap2.serialization.KvmSerializable; import org.ksoap2.serialization.PropertyInfo; public class Category implements KvmSerializable { public int CategoryId; public String Description; public String Name; public Category(){} public Category(int categoryId, String description, String name) { CategoryId = categoryId; Name = name; Description = description; } @Override public Object getProperty(int arg0) { switch(arg0) { case 0: return CategoryId; case 1: return Description; case 2: return Name; } 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.INTEGER_CLASS; arg2.name = "CategoryId"; break; case 1: arg2.type = PropertyInfo.STRING_CLASS; arg2.name = "Description"; break; case 2: arg2.type = PropertyInfo.STRING_CLASS; arg2.name = "Name"; break; default:break; } } @Override public void setProperty(int arg0, Object arg1) { switch(arg0) { case 0: CategoryId = Integer.parseInt(arg1.toString()); break; case 1: Description = arg1.toString(); break; case 2: Name = arg1.toString(); break; default: break; } } } 
0
source share
2 answers

Try using

 private static final String NAMESPACE = "http://ws.chathura.com/xsd"; 

in your Android activity and add getters and setters to your Category class on the client.

0
source

Ok, I tried something with your advice, and now I'm very close to the solution:

I found out that I need 2 namespaces (one for receiving and one for sending)

So, I am making the following changes:

 private static final String NAMESPACE = "http://ws.chathura.com"; private static final String NAMESPACE2 = "http://ws.chathura.com/xsd"; 

and this:

 SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); ... ... envelope.addMapping(NAMESPACE2, "Category",new Category().getClass()); 

Now my Webservice receives my Category object, but the first attribute from the category ( CategoryID ) is not passed, and the following exception is shown in LogCat:

  06-13 09:59:17.459: W/System.err(647): java.lang.RuntimeException: Unknown Property: categoryId 06-13 09:59:17.469: W/System.err(647): at org.ksoap2.serialization.SoapSerializationEnvelope.readSerializable(SoapSerializationEnvelope.java:200) 06-13 09:59:17.469: W/System.err(647): at org.ksoap2.serialization.SoapSerializationEnvelope.readInstance(SoapSerializationEnvelope.java:444) 06-13 09:59:17.469: W/System.err(647): at org.ksoap2.serialization.SoapSerializationEnvelope.read(SoapSerializationEnvelope.java:387) 06-13 09:59:17.469: W/System.err(647): at org.ksoap2.serialization.SoapSerializationEnvelope.readUnknown(SoapSerializationEnvelope.java:273) 06-13 09:59:17.469: W/System.err(647): at org.ksoap2.serialization.SoapSerializationEnvelope.read(SoapSerializationEnvelope.java:389) 06-13 09:59:17.469: W/System.err(647): at org.ksoap2.serialization.SoapSerializationEnvelope.parseBody(SoapSerializationEnvelope.java:151) 06-13 09:59:17.469: W/System.err(647): at org.ksoap2.SoapEnvelope.parse(SoapEnvelope.java:140) 06-13 09:59:17.469: W/System.err(647): at org.ksoap2.transport.Transport.parseResponse(Transport.java:100) 06-13 09:59:17.469: W/System.err(647): at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:197) 06-13 09:59:17.479: W/System.err(647): at com.androidclient.ws.WSClientActivity$1$1.run(WSClientActivity.java:91) 06-13 09:59:17.479: W/System.err(647): at java.lang.Thread.run(Thread.java:1019) 

I tested it a second time without CategoryID , but then Description unknown property: - (

What's wrong?

EDIT:

I think the exception is due to the different namespace in envelope.addMapping . What can I do to use only one namespace?

0
source

Source: https://habr.com/ru/post/1494055/


All Articles