Using KXML Parser to Fetch Data from a Server in J2ME


This tutorial is not as detailed as the previous ones. It seeks to guide you on how you can connect your J2ME application to an online server or a server on your local machine so that you are able to fetch data dynamically. I have done some code snippets but as I said it is just a simple guide so please do more research by ourself. The steps are as follows

1.    Generating XML on the server side
You can either use RSS feeds or generate your own xml. For most websites we have automated RSS generators. The parsing methods are the same since both of them are basically xml
The code snippet below shows how you can generate your own XML feed
/* the first step is retrieving the data from the database. My assumption is you have a MySQL  resultset stored in the variable $_venue */
$returnXml  = ‘<?xml version=”1.0″ encoding=”iso-8859-1″?>’; //create an xml //file
$returnXml.='<details>’; //the opening tag for your xml file
$returnXml.='<item>’;
$returnXml.='<id>’.$_venue->id.'</id>’; //stuff you want to retrieve
$returnXml.='<location>’.$_venue>street.'</location>’;
$returnXml.='<checkins>’.$_venue->checkins.’ are checked in at this venue</checkins>’;
//you can add more attributes depending on the data you are retrieving
$returnXml.='<reviews>’; //you can do xml nesting.
foreach ($reviewDet as $review) /* $reviewDet is an array of results so we need to loop through it to get each individual field */
{
$rev_link=’index.php?option=com_eventlist&view=events&layout=venue&device=phone&action=review&rev_id=’. $review->id;
$rev_link = JRoute::_( $rev_link );
$returnXml.='<revDetails>’;
$returnXml.='<rev_name>’.$review->rev_title.'</rev_name>’;
$returnXml.='<rev_text>’.$review->rev_review.'</rev_text>’;
$returnXml.='<rev_link>’.$rev_link.'</rev_link>’;
$returnXml.='</revDetails>’;
}

$returnXml.='</reviews>’; //close the review
$returnXml.='</item>’;//close item
$returnXml.='</details>’; //close details
header(“Content-type: text/xml; charset: iso-8859-1”); //set xml content type
ob_start(); //start display
echo $returnXml; //echo the data we have appended to $returnXml
ob_flush(); //flush it to the display, not a must but a good precaution
exit;    /* return control to invoking method, ensures that the user is not to the website */

To access this xml all we need to do is pass the relevant url to the invoking method and it will return a properly formatted xml document.
Example in Joomla

The above url depends entirely on how you make calls to functions in your implementation

2.    Configuring KXML Parser in J2ME
This actually is a simple step. Just as we included the LWUIT jar, in order to use KXML parser we just need to include the jar in our resource path and we are done. Search for the KXML jar online, I have a very old version

3.    Consuming XML in J2ME – Creating the parser
This involves two steps
•    Creating an class to use to store our objects
•    The actual parsing
The code snippet below shows how to create the class for holding our data. It is the normal Java class. To create it you select Java class and not a midlet. This class is using the data we created in the first step but without the review part
public class RssItem { //you can change the name to whatever you want
public String id; //declare the variables you are fetching from server side
public String location;
public String checkins;
public RssItem(String theId,String location,String checkins) /*you can add more parameters depending on the data you are fetching */
{
this.id=theId;
this.location=location;
this.checkins=checkins;
}
public RssItem()  //we need the default constructor, you must create it
{

}
}
Now that we have created the class we need to parse the data. The code snippet below shows how this can be achieved

public Vector parse(final String rssUrl) throws Exception {  /* the data is going to be returned as a vector. We pass the url you are retrieving from as a parameter to allow us re-use this method */

final Vector items = new Vector();
genP.progressBar();  /* this is just a method to indicate to the user that something is going on in the background */
Display.getInstance().invokeAndBlock(new Runnable() {  //this is how threading is done in Lwuit

public void run() {
KXmlParser parser = null;  /* create an instance of KXML parser, you also need the objects created below */
HttpConnection conn = null;
InputStream rssStream = null;
InputStreamReader isr = null;
try {
parser = new KXmlParser();
System.out.println(rssUrl);
conn = (HttpConnection) Connector.open(rssUrl); //open the connection
conn.setRequestMethod(“GET”); // set the request method. For post we don’t need to parse
conn.setRequestProperty(“User-Agent”, “Profile/MIDP-1.0 Configuration/CLDC-1.0”); /* required by browsers , differentiates between requests from different sources */
if (conn.getResponseCode() == HttpConnection.HTTP_OK) {  /* There are several responses, we need an OK response to proceed . */
String str;
rssStream = conn.openInputStream();
int lenght = (int) conn.getLength();
System.out.println(“lenght of stream: ” + lenght);
if (lenght != -1) {
byte serverData[] = new byte[lenght];
rssStream.read(serverData);
str = new String(serverData);
} else {
ByteArrayOutputStream bStrm = new ByteArrayOutputStream();
int ch;
while ((ch = rssStream.read()) != -1) {
bStrm.write(ch);
}
str = new String(bStrm.toByteArray());
bStrm.close();
}
byte[] payload = str.getBytes();
ByteArrayInputStream bain = new ByteArrayInputStream(payload);
isr = new InputStreamReader(bain);
parser.setInput(isr);
//at this point we have retrieved the necessary, now we need to parse it in order to separate the data
parser.nextTag();

parser.require(XmlPullParser.START_TAG, null, “details”);  /* state the opening tag for our xml, needs to match with the one we specified otherwise parsing will fail
parser.nextTag();
while (parser.getEventType() != XmlPullParser.END_TAG) { /* loop to make sure we get to the end of our xml */
String nodeName = parser.getName(); //get the name of the current node

if (nodeName.compareTo(“item”) == 0) { /*comparison necessary if there are several choices for tags */
items.addElement(parseRssItem(parser)); /* we are adding items to our vector. The invoked method returns an RssItem */
// System.out.println(“Item added”);
} else {
parser.skipSubTree();
}
parser.nextTag();
}
}
} catch (Exception ioe) {
Dialog.show(“Error”, “Error connecting to the internet”, “Exit”, null);
ioe.printStackTrace();
} finally {
try {
if (isr != null) {
isr.close();
}
if (rssStream != null) {
rssStream.close();
}
if (conn != null) {
conn.close();
}

} catch (IOException i) {
i.printStackTrace();
}

}
}
});

return items;
}
The method below does the actual data retrieval and adds the data to the RssItem object that we will create. We then append it to our vector. Note that this method is invoked by the above method
RssItem parseRssItem(KXmlParser parser) throws Exception { /* the method returns an RssItem, the parameter is the KXML Parser created in the previous method */
RssItem item = new RssItem(); //create the RssItem we will append data into

parser.nextTag();

while (parser.getEventType() != XmlPullParser.END_TAG) { //make sure we loop through all tags
String nodeName = parser.getName();

if (nodeName.compareTo(“id”) == 0) { /*do a comparison then append to the RssItem as defined in the RssItem class */
item.id = parser.nextText();  /*remember we created a String called id in RssItem, we are accessing it using the . operator */
} else if (nodeName.compareTo(“location”) == 0) {
item.location = parser.nextText();
} else if (nodeName.compareTo(“checkins”) == 0) {
item.checkins = parser.nextText();
} else {
parser.skipSubTree();
}
parser.nextTag();
}
return item;
}

The steps above have enabled use insert our data from the server side into vector, how do we access them?

4.    Using the Vector in J2ME
To use the data we just need to invoke the method we created, pass a url and it will return a vector. This is demonstrated in the code snippet below

KXmlRssParser parser=new KXmlRssParser(); //this is the parser class we created
Vector detailsVector = null;
try {
detailsVector = parser.parse(url);
/*depending on our result set we can either loop through the vector or just access the data directly using index 0. */
String location = “”;
location = ((RssItem) detailsVector.elementAt(0)).location; /*Cast to RssItem, elementAt(0) if we know the exact location otherwise loop, .location is how we added it in the parser */
//you can retrieve the rest and use it the way you want

} catch (Exception e) {
e.printStackTrace();
}

You can download a pdf version of this tutorial here If you have any questions, suggestions or comments feel free to leave a comment.

Advertisements

3 thoughts on “Using KXML Parser to Fetch Data from a Server in J2ME

  1. Please do see into the case, that probably this application does not parse and display images on your form, I am looking for an a sample code snippet which shows the images in the form, (Which I have kinda of implemented), now the problem here is I am loading approximately 50 Images from an XML Parser directly using a separate thread, but still the application has really slowed down, could you please implement the concept of Lazy Loading and implement the same, just as SHAI had implemented in his Million Image List, the concept of Lazy Loading has been implemented, so please do lookup for the same and reply me as soon as possible.

    You may mail me at : vicky_cancer14@yahoo.com
    Call me up at : +91 9876749674

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s