KSoap2和KvmSerializable – 如何发送像Stringarrays这样的复杂对象

我想从我的Ksoap客户端向我的web服务发送一个复杂的对象。 这是我的class级类别的对象。 该代码基于本教程的示例:

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

Web服务正在运行,WSDL文件显示类别对象。 但是,如果我将类别对象发送到我的soap webservice,则会出现以下错误:

[错误]尝试调用服务方法时发生exceptiongetCategoryObject org.apache.axis2.AxisFault:未知类型{http://ws.chathura.com}类别Logcat显示以下内容:06-12 11:08:57.576:W /System.err(777):SoapFault – faultcode:’soapenv:Server’faultstring:’Unknow type {http://ws.chathura.com} Category’faultactor:’null’detail:org.kxml2.kdom.Node @ 4054a528

这是我在Tomcat 7上运行的Java Webservice:

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; } } 

这是我在WebServer上的Category类:

 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; } } 

这是WSDL文件:

  This XML file does not appear to have any style information associated with it. The document tree is shown below.  Please Type your service description here                                                                                         

这是我的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(); } } } 

这是Android客户端的类别类:

 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; } } } 

尝试使用

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

在您的Android活动中,将getter和setter添加到客户端的Category类中。

好的,我已经尝试了你的提示,现在我非常接近解决方案:

我发现,我需要2个名称空间(一个用于接收,一个用于发送)

所以我做了以下更改:

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

和这个:

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

现在我的Webservice收到了我的对象类别 ,但是不传输Category( CategoryID )中的第一个属性,LogCat显示以下exception:

  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) 

我没有使用CategoryID进行了第二次测试,但随后是Description未知属性:-(

哪里不对?

编辑:

我认为exception是因为envelope.addMapping命名空间不同。 我该怎么办,只使用一个命名空间?