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

Web and WebWorks Development

Calling a web service from a BlackBerry WebWorks Application

by BlackBerry Development Advisor on ‎07-29-2010 12:47 PM - edited on ‎01-07-2011 01:30 PM by BlackBerry Development Advisor (10,782 Views)

Summary

 

This article applies to the following:

 

  • BlackBerry® WebWorks™ applications

 

Details

 

I've participated in a bunch of threads about calling web services from WebWorks applications.  A bunch of these threads have been around ASP.NET.  So I figured I would create a post showing how I would go about writing a web service written in ASP.NET that I would then access from my BlackBerry WebWorks application.

 

To start off with, I figured I would create an example where I had an existing ASP.NET web service that I wanted to extend to mobile.  The first rule of thumb is that SOAP web services are INCREDIBLY BLOATED with tons of mark-up and syntax that you typically don't need.  It was designed with server to server data transfer using a wired connection in mind.

 

This becomes especially apparent in the mobile world as you are going to have to process all of that bloat on the client and then transform it into something meaningful.  What I like to do is create some small wrapper methods on an existing web service interfaces so that it can continue to be used by those who want to call the pre-existing methods directly via SOAP, but also have an additional much more efficient mobile friendly JSON interface.  This allows me the ability to provide a nice end result without ever having to change any logic from my existing web service interfaces.

 

While my examples below are shown in ASP.NET (because I'm a .NET junkie), the same principals can be applied to all web services written in any language.

 

Looking at JSON

 

JSON can be your best friend when it comes to bringing back data.  Basically once JSON is parsed it becomes a JavaScript® object.  You can look at it as built in deserialization from a string.

 

There are a TON of JSON parsers out there for pretty much any language you can think of.  For details on all the available parsers take a look at http://json.org/

 

For my example, I chose the JavaScript JSON toolkit from http://code.google.com/p/json-sans-eval/.  For my server side I just created the JSON syntax myself manually, but there are toolkits for that as well.

 

web.config

 

<system.web>
<webServices>
<protocols>
<add name="HttpSoap"/>
<add name="HttpGet"/>
</protocols>
</webServices>
......

 If you are wanting to pass down parameters using POST and GET you will need to enable these protocols for your ASP.NET web service.  They were turned off by default starting with Microsoft® .NET framework 2.0.

 

 

My server side code:

 

using System;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Linq;
using System.Xml.Serialization;

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Service : System.Web.Services.WebService
{
public Service () { }

[WebMethod]
public Car GetCar(String make, String model)
{
Car car = new Car();
car.Make = make;
car.Model = model;
car.Year = 2002;
return car;
}

[WebMethod]
public String GetCarJSON(String make, String model)
{
return GetCar(make, model).toJSON();
}
}

public class Car : Object
{
public String Make = String.Empty;
public String Model = String.Empty;
public int Year = 0;

public String toJSON()
{
String result = "{" +
"\"Make\": \"" + this.Make + "\", " +
"\"Model\": \"" + this.Model + "\", " +
"\"Year\": \"" + this.Year + "\"" +
"}";
return result;
}
}

 

 

You will see that I created a GetCarJSON() companion method that acts as a quick wrapper around the main GetCar() method that was previously exposed.  This gives my mobile a nice alternative method to call that will then return JSON instead of SOAP XML.  You can entirely re-use your existing methods without change.

 

To complete this simplification, I added a toJSON() method on my Car object.  This will then serialize the object into its JSON representation.  

 

Note: Please forgive my code "casing" between C# and JavaScript... I have too many languages running around in my head  :smileyhappy:

 

Now let's look at the Client side code:

 

 

<html>
<head>
<meta name="viewport" id="viewport" content="initial-scale=1.0,user-scalable=no" />
<script type="text/javascript" src="json_sans_eval.js"></script>
<script type="text/javascript">
var xmlHttp = new XMLHttpRequest();

function doClick() {
var url = "http://localhost:4100/service/service.asmx/GetCarJSON?make=Subaru&model=WRX";
xmlHttp.open('GET', url, true);
xmlHttp.onreadystatechange = callbackFunction;
xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
document.getElementById('results').innerHTML = "Requesting...";
xmlHttp.send(null);
}

function callbackFunction(){
if (xmlHttp.readyState != 4)
return;

var result = xmlHttp.responseXML.documentElement;
var jsonString = result.childNodes[0].nodeValue;

// I used the JSON parser found here http://code.google.com/p/json-sans-eval/
var car = jsonParse(jsonString);

var innerHTML = "<div><b>Make:</b>" + car.Make + "</div>\n" +
"<div><b>Model:</b>" + car.Model + "</div>\n" +
"<div><b>Year:</b>" + car.Year + "</div>\n";

document.getElementById('results').innerHTML = innerHTML;
}
</script>
</head>
<body>
<button onclick="doClick()">Get Single Object</button>
<div id="results"></div>
</body>
</html>

Here I make a simple XMLHttpRequest to the URL for the GetCarJSON() function.  Since the results being returned are well formed XML I can then retrieve the contents of the results from the responseXML property of the XHR object.  From there I grab the contents of my JSON string from the first child node.

 

Here is where the JSON parser comes in, simply call jsonParse() and my string is now a Car JavaScript object that I can interact with.  JSON allows for all kinds of data structures so that you can replicate pretty much any object you wish to return.

 

Passing down objects to your web service from the client is simply the same process in reverse.

 

What if you don't have access to the web service source?

 

My recommendation is that if you have an existing SOAP web service that you wish to call and you do not have access to changing its source code, that you should create a small server side wrapper around this web service and provide your JSON data back out of your own web service.

 

This allows for two main benefits:

  1. Light weight JSON data going to-and-from your mobile application
  2. A layer of abstraction between a Web Service interface that you do not control and your mobile application.

Should this third-party interface change, you can abstract those changes away from your mobile client.

 

Even More Optimized!

 

You can even take this further by returning <div> statements from your web service instead of JSON.  This is particularly good if you are returning data that is simply for display and does not need to be manipulated in code.  You can then simply dump in the <div> using the innerHTML of an element and not have to do any client side processing.  Since it is returned as a <div> with no formatting, you can then apply a client side CSS to layout the data as you see fit.

 

 

Summary

 

Web services can be really easy to access using a BlackBerry WebWorks application.  There's no need for complicated Java extensions or other heavy options.  Hopefully you will find this information useful and possibly help you out of a bind.

Users Online
Currently online: 16 members 597 guests
Please welcome our newest community members: