Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Contributor
Musipoo
Posts: 41
Registered: ‎02-04-2013
My Device: Bold 9900

KSOAP2 - Mapping complex types problem (StackOverflowError)

[ Edited ]

 

Hi there,

 

I'm working with the Ksoap-API and wrote a Java app communicating with a .NET webservice. The plain response is a complex SoapObject of anytype, I've tried to map the response to retrieve the actual properties - analogue to some examples I've found on some developer forums. Although these examples seem to work out fine I still got some issues with mine.

 

1) I'm not quite sure how to access the single properties after mapping (see below, I've tried it with the mappedResponse variable)

2) Far worse: I get an StackOverflowError, I assume it's the getProperty()-method (see below)

 

I'll post my source code since I could not find any post dealing with the exact same problems so far. Any help would be so appreciated!! I'm struggling with this for weeks now..

 

 


 

 

The Soap response:

 

<?xml version="1.0" encoding="utf-8"?> 
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<getOffeneAusfaelleResponse xmlns="http://xxx.de">
<getOffeneAusfaelleResult>
<Anwendung>
<ID>int</ID>
<Name>string</Name>
<LastAusfall>
<ID>int</ID>
<WITID>int</WITID>
<Verursacher>int</Verursacher>
<RZAlarm>boolean</RZAlarm>
<AusfallStartDate>dateTime</AusfallStartDate>
<AusfallStopDate>dateTime</AusfallStopDate>
<AusfallGenDate>dateTime</AusfallGenDate>
<AusfallCloseDate>dateTime</AusfallCloseDate>
<LastUpdateFrom>string</LastUpdateFrom>
<Ausfallgrund>string</Ausfallgrund>
<Auswirkungen>string</Auswirkungen>
<AnzBetrfAnwender>int</AnzBetrfAnwender>
<MeldungDurch>string</MeldungDurch>
<TicketNr>string</TicketNr>
<Statis xsi:nil="true" />
<Alarmierungen xsi:nil="true" />
</LastAusfall>
<CurrentStatus>Ausfall or Eingeschraenkt or Verfuegbar or NotSet</CurrentStatus>
<Beschreibung>string</Beschreibung>
<ObererWitKnoten>int</ObererWitKnoten>
</Anwendung>

<Anwendung>
<ID>int</ID>
<Name>string</Name>
<LastAusfall>
<ID>int</ID>
<WITID>int</WITID>
<Verursacher>int</Verursacher>
...
...
<Statis xsi:nil="true" />
<Alarmierungen xsi:nil="true" />
</LastAusfall>
<CurrentStatus>Ausfall or Eingeschraenkt or Verfuegbar or NotSet</CurrentStatus>
<Beschreibung>string</Beschreibung>
<ObererWitKnoten>int</ObererWitKnoten>
</Anwendung>
</getOffeneAusfaelleResult>
</getOffeneAusfaelleResponse>
</soap:Body> </soap:Envelope>

 

When I ask for the plain response (without the mapping) it is somewhat like:

 

anyType{
     Anwendung=anyType{
                   ID=12345;
                   Name=Service1;
                   LastAusfall=anyType {
                                     ID=12345;
                                     WITID=12345;
                                     Verursacher=-1;
                                     RZAlarm=true; .. ..}

 

 

 The main Java class doing the Http-call and mapping: (HelloWorld.java)

 

package mypackage;

import java.io.IOException;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransport;
import org.xmlpull.v1.XmlPullParserException;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;

public class HelloWorld extends UiApplication {
	public static void main(String[] args) {
		HelloWorld theApp = new HelloWorld();
		theApp.enterEventDispatcher();
	}

	public HelloWorld() {
		pushScreen(new HelloWorldScreen());
		String serviceUrl = "http://xxxxxxx.asmx?WSDL";
		String serviceNamespace = "http://xx.yy.de/";
		String soapAction = "http://xx.yy/method";
		final SoapObject request = new SoapObject(serviceNamespace,
				"getOffeneAusfaelle");
		final SoapObject response = new SoapObject(serviceNamespace,
				"getOffeneAusfaelleResponse");
		response.addProperty("getOffeneAusfaelleResult",
				new OffeneAusfaelleResult());
		final SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
				SoapEnvelope.VER11);
		envelope.bodyOut = request;
		envelope.setOutputSoapObject(response);
		envelope.addMapping(serviceNamespace, "getOffeneAusfaelleResponse",
				OffeneAusfaelleResponse.OFFENEAUSFAELLERESPONSE_CLASS);
		envelope.addMapping(serviceNamespace, "getOffeneAusfaelleResult",
				OffeneAusfaelleResult.OFFENEAUSFAELLERESULT_CLASS);
		envelope.addMapping(serviceNamespace, "Anwendung",
				Anwendung.ANWENDUNG_CLASS);
		envelope.dotNet = true;
		envelope.encodingStyle = SoapSerializationEnvelope.XSD;
		final HttpTransport http = new HttpTransport(serviceUrl);
		http.debug = true;
		OffeneAusfaelleResult mappedResponse = null;
		try {
			http.call(soapAction, envelope);
			System.out.println((OffeneAusfaelleResult) envelope.getResponse());
			mappedResponse = ((OffeneAusfaelleResult) envelope.getResponse());
		} catch (IOException ex) {
			ex.printStackTrace();
		} catch (XmlPullParserException ex) {
			ex.printStackTrace();
		}
		((HelloWorldScreen) this.getActiveScreen())
				.setScreenTest("MappedResponse:" + mappedResponse);
	}
}

final class HelloWorldScreen extends MainScreen {
	public RichTextField textField;

	public HelloWorldScreen() {
		super();
		LabelField title = new LabelField("DVZ_KSOAP2", LabelField.ELLIPSIS
				| LabelField.USE_ALL_WIDTH);
		setTitle(title);
		textField = new RichTextField("Keine Ausfälle");
		add(textField);
	}

	public void setScreenTest(String text) {
		textField.setText(text);
	}
}

 

 

 I've read that I have to map <Anwendung> and the wrappers <getOffeneAusfaelleResult> and <getOffeneAusfaelleResponse> so these are the associated classes:

(first I just tried to retrieve the first two values Name and Id)

 

Anwendung.java:

 

package mypackage;

import java.util.Hashtable;
import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.PropertyInfo;

public class Anwendung implements KvmSerializable {
	public static final Class ANWENDUNG_CLASS = new Anwendung().getClass();
	private Integer id = null;
	private String name = null;

	public Object getProperty(int index) {
		switch (index) {
		case 0:
			return this.id;
		case 1:
			return this.name;
		default:
			return null;
		}
	}

	public int getPropertyCount() {
		return 2;
	}

	public void getPropertyInfo(int index, Hashtable properties,
			PropertyInfo info) {
		switch (index) {
		case 0:
			info.type = PropertyInfo.INTEGER_CLASS;
			info.name = "ID";
			break;
		case 1:
			info.type = PropertyInfo.STRING_CLASS;
			info.name = "Name";
		default:
			break;
		}
	}

	public void setProperty(int index, Object value) {
		switch (index) {
		case 0:
			this.id = Integer.valueOf(value.toString());
			break;
		case 1:
			this.name = value.toString();
			break;
		default:
			break;
		}
	}
}

 

 

OffeneAusfaelleResponse.java:

 

package mypackage;

import java.util.Hashtable;
import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.PropertyInfo;

public class OffeneAusfaelleResponse implements KvmSerializable {
	public static final Class OFFENEAUSFAELLERESPONSE_CLASS = new OffeneAusfaelleResponse()
			.getClass();
	private OffeneAusfaelleResult offeneAusfaelleResult = new OffeneAusfaelleResult();

	public Object getProperty(int index) {
		return this.offeneAusfaelleResult;
	}

	public int getPropertyCount() {
		return 1;
	}

	public void getPropertyInfo(int index, Hashtable properties,
			PropertyInfo info) {
		info.name = "getOffeneAusfaelleResult";
		info.type = OffeneAusfaelleResult.OFFENEAUSFAELLERESULT_CLASS;
	}

	public void setProperty(int index, Object value) {
		this.offeneAusfaelleResult = (OffeneAusfaelleResult) value;
	}
}

 

 

OffeneAusfaelleResult.java:

 

package mypackage;

import java.util.Hashtable;
import java.util.Vector;
import org.ksoap2.serialization.KvmSerializable;
import org.ksoap2.serialization.PropertyInfo;

public class OffeneAusfaelleResult extends Vector implements KvmSerializable {
	public static final Class OFFENEAUSFAELLERESULT_CLASS = new OffeneAusfaelleResult()
			.getClass();

	public Object getProperty(int index) {
		return this.getProperty(index);
	}

	public int getPropertyCount() {
		return 1;
	}

	public void getPropertyInfo(int index, Hashtable properties,
			PropertyInfo info) {
		info.name = "Anwendung";
		info.type = Anwendung.ANWENDUNG_CLASS;
	}

	public void setProperty(int index, Object value) {
		this.add((Anwendung) value);
	}

	private void add(Anwendung value) { 
		//TODO Auto-generated method stub
		}
	}

 

 

In debug mode I can see that  this.getProperty(index) in OffeneAusfaelleResponse.java is called over and over again, and the index property is always 0.. how can I avoid this StackOverflow? Is it called recursively because it can't find any property?

 

public Object getProperty(int index) {
	return this.getProperty(index); 
} 

  


Am I missing something important?

Thank you so much in advance!!

 

Cheers, Musipoo