MOBILE

BlackBerry Java Application Development : Networking - parsing the response

6/11/2012 11:38:49 AM
  1. You've already seen the output for a call to the CopyMe service. Even so, when creating a custom Handler for a specific response it's a good idea to have a copy of the raw XML response handy to compare with and view. The first step in implementing a parser is to create that custom Handler class.

  2. Create a new class in the existing HttpBasics namespace and call it CopyMeHandler.

  3. Insert the following code into the class stub that is created.

    private String currentElement;
    public String copymeResponse;
    public void startElement(String uri, String localName, String qName, Attributes attributes)
    {
    currentElement = localName;
    }
    public void characters(char[] ch, int start, int length)
    {
    if ( currentElement.equals( "string" ) )
    {
    copymeResponse = new String( ch, start, length );
    }
    }
    
    
    					  
  4. Now, you need to modify the updateDestination method of the HttpBasicsMainScreen. Previously, it displayed the raw output into the _Output field. Now, however, you need to parse the output and display only the results. Comment out the existing contents of the run method.

  5. Then insert the following code into the run method.

    SAXParserImpl parser = new SAXParserImpl();
    CopyMeHandler handler = new CopyMeHandler();
    ByteArrayInputStream inputStream = new ByteArrayInputStream( text.getBytes());
    try
    {
    parser.parse( inputStream, handler );
    }
    catch ( Exception e )
    {
    _Output.setText( "Unable to parse response.");
    return;
    }
    _Output.setText( handler.copymeResponse );
    
    
    					  

What just happened?

Now when you click on the Post Data menu and call the CopyMe service, the data that is shown in the output window is the text that has been returned by the web service response. As the text is the same as what was in the Copy Source field, it isn't too interesting, but it's a lot better than the raw XML response. Now, let's take a closer look at what you've changed and how it works.

The first step that you took was to create a new handler for the CopyMe service that will be used with the SAX parser. This new handler is about as simple as one can get because there is just one element being returned, not including the XML header element.

This new class utilizes only two of the methods that are available-the startElement and characters methods.

As the name suggests, the startElement method is called each time a new element is encountered in the XML. This method provides only a little detail, including the name of the new element. Also notice what it doesn't provide, and that is any information about the parenting or position of this node in relation to others in the file. All you need to do in this method is to save the name of the node in a member variable before the processing continues.

public void startElement(String uri, String localName, String qName, Attributes attributes)
{
currentElement = localName;
}


					  

The other method that you overrode in this class is called characters. This method is called after parsing the inner text of an element, that is the text between the start and end tags, which is not otherwise within a tag. If the element name that we are currently processing is called "string", then the inner text will contain the value of the string that has been returned by the web service. We capture this value in another member variable so that it can be retrieved later.

Again, notice that this method does contain any other contextual information about the element containing the text. This is why you need to override the startElement method and keep track of which element you are currently processing. Because you know that there is only one element named "string" in the XML this simple logic works. However, for large and complex XML files, a lot more complex logic will be needed.

public void characters(char[] ch, int start, int length)
{
if ( currentElement.equals( "string" ) )
{
copymeResponse = new String( ch, start, length );
}
}

The DefaultHandler class provides a lot of possible override points that you can take advantage of to perform more complex processing of XML. Remember though, that this is a Simple API for XML so you really can't get too complex. Still, methods such as startDocument, endElement, and error can be used to cover most scenarios.

The startElement method though is probably one of the most important methods in this class. In addition to the element name you are also provided with an array of attributes that are attached to the element. Most of the time, the data you are looking for will be found in the inner text or one of the attributes of an element.

The last step is to change the behavior of the updateDestination method so that response is parsed out by using the SAX Parser and only the real response data will be put into the _Output field.

Initial setup is simple by creating the SAXParser and the Handler objects. Notice that we're actually creating a SAXParserImpl object and not a SAXParser object. This is because the SAXParser class is an abstract class, and by definition, cannot be instantiated. This was done so that other implementations of the SAX Parser could be created if there was a special condition that wasn't handled otherwise. I don't know what that might be, but the capability is there if needed.

As part of the setup, you also need to create a stream that the parser can consume. It's kind of silly because the data comes in from a stream in the thread and is converted into a string as it is read in. Then, in this step, you convert the string back into a stream so that it can be parsed.

SAXParserImpl parser = new SAXParserImpl();
CopyMeHandler handler = new CopyMeHandler();
ByteArrayInputStream inputStream = new ByteArrayInputStream(text.getBytes());


					  

The actual parsing must be in done in an exception block in case there are catastrophic problems. In this case, we simply set the output to indicate there is an error in the catch block. The call to the parse method is where the actual work of parsing the output is done. The parse method then makes calls to the methods you have implemented in the CopyMeHandler and which ultimately retrieves the value from the XML.

try
{
parser.parse( inputStream, handler );
}
catch ( Exception e )
{
_Output.setText( "Unable to parse response.");
}

Lastly, if there are no problems parsing the response we set the _Output field to the real response text and not just the raw XML. Remember, the response text was added to the copymeResponse data member as part of the characters method in the handler class. Now that the parsing is completed, that member should contain the value.

_Output.setText( handler.copymeResponse );

So far you've seen how to call a basic web service by using a basic HTTP POST command and have introduced the SAX parser as a way to parse data from the response. These examples have so far been very simple; trivial really. Web services can be much more complicated so the question is, how well does this technique scale?

You can use an HTTP POST command to call web services as long as the data being passed to a web service is a string. The return data can be as complex as you want it, because it all gets serialized into XML anyway. It's the sending part that will only work if the data is a string.

If you must work with more complex data types then you must use SOAP requests instead of an HTTP POST request. One possibility is to use the kSOAP2 library-an open source project hosted at SourceForge (http://ksoap2.sourceforge.net/). Another is the Sun Java Wireless Toolkit for CLDC (http://java.sun.com/products/sjwtoolkit/). Even though the toolkit has been rolled into the Java ME SDK 3.0 you can still download the 2.0 libraries and use them with the BlackBerry SDK, which supports only Java ME 2.0. Using this toolkit will actually create service stubs that handle the SOAP envelope creating and parsing for you so you wouldn't need the SAX parser to get data out. Instead, data would be nicely wrapped up in a class much like you would experience when using a web service in Visual Studio.

There is another approach that is recommended if you have control over both the client and server-side communication. If you have control over both sides you have a lot more flexibility. One thing that you always want to think about with network communications is how much data is being transmitted over the network. Web services with SOAP and XML are great as standards go, but they can also be very verbose and cause a lot of traffic to be generated. If you control both sides of communication you can eliminate a lot of this extra traffic by transferring XML snippets, or even JSON formatted data instead of a full SOAP packet.

This would mean that your services wouldn't be easily reusable by other platforms, but the performance and simplicity of your mobile client-side are significantly better. Consider the very simple example that we did with the CopyMe service. If you exchanged a single XML snippet or JSON formatted string then the code to call the web service is exactly the same! Your data can be as complex as you need it to be but your network communication code isn't.

Now that we've covered the details in the code for sending data, let's take a look at the transport possibilities that are available.

Other  
  •  BlackBerry Java Application Development : Networking - calling a web service
  •  Ipad : Presentations with Keynote - Adding Transitions (part 2) - Object Transitions
  •  Ipad : Presentations with Keynote - Adding Transitions (part 1) - Magic Move
  •  What the world is waiting for ?
  •  Galaxy Tab 10.1 - Touchy-feely
  •  Le Pan II - Entry-level Honeycomb tablet
  •  Mobile - The Good, The Budget And The Surprising
  •  The Blackberry OS 2.0 - So, The Playbook Is Whole
  •  Mobile Phone Update Fever (Part 4)
  •  Mobile Phone Update Fever (Part 3)
  •  Mobile Phone Update Fever (Part 2) - Social integration, Multitasking & Tablets
  •  Mobile Phone Update Fever (Part 1) - Apple iOS 5, Google Android 4.0 & Microsoft Windows Phone 7.5
  •  Mobile - Four Cores Good, Two Cores Bad
  •  Mac - That Syncing Feeling
  •  Toshiba Regza Tablet AT200 - The Thinnest
  •  ASUS Transformer Pad - Transforming Value to Quality
  •  Sony Xperia S - A Fresh Xperience
  •  Targus Travel Chill Mat - Chillin' On-The-Go
  •  Kingston Wi-Drive - Rekindling The Wi-Drive
  •  Bootleg Unzipped (Part 2) - An industry of fakes
  •  
    Top 10
    Nikon 1 J2 With Stylish Design And Dependable Image And Video Quality
    Canon Powershot D20 - Super-Durable Waterproof Camera
    Fujifilm Finepix F800EXR – Another Excellent EXR
    Sony NEX-6 – The Best Compact Camera
    Teufel Cubycon 2 – An Excellent All-In-One For Films
    Dell S2740L - A Beautifully Crafted 27-inch IPS Monitor
    Philips 55PFL6007T With Fantastic Picture Quality
    Philips Gioco 278G4 – An Excellent 27-inch Screen
    Sony VPL-HW50ES – Sony’s Best Home Cinema Projector
    Windows Vista : Installing and Running Applications - Launching Applications
    Most View
    Workgroup All-In-One : Samsung Clx-6220fx
    iTunes Match Q&A
    Using Non-Windows Systems to Access Exchange Server 2010 : Outlook Express
    Component Watch: Looking back
    Designing a Windows Server 2008 R2 Active Directory : Understanding AD DS Domain Design
    Creative software
    SQL Server 2008 : Explaining Advanced Query Techniques - Managing Internationalization Considerations
    Corsair Vengeance M90 - Play With A Vengeance
    Programming .NET Framework 3.5 : Using Data Synchronization Services (part 1)
    Adobe Photoshop CS5 : PDF Essentials - Compression Options for Adobe PDF
    Working with the REST API
    The Invisible Web (Part 2) - WWW Virtual Library, CompletePlanet & Infoplease
    Home Theatre Pc Software And Operating Systems (Part 7) - Playing Back Blu-rays
    Programming .NET Components : Remoting - The .NET Remoting Architecture
    Corsair Obsidian 800D
    IIS 7.0 : Performance and Tuning - Processor
    Nexus 7 – Benchmark Score
    Zotac Geforce GTX 670 AMP! Edition
    Flora - Nature - Photo Expert (Part 4) - Viewpoint
    Build Up Your Dream House with PC (Part 2)