Currently Being Moderated

In this series of blog entries we will describe the development of a mobile chat app using SAP NetWeaver Cloud as a backend. The last time we explained the functionality and the architecture of our app. Now we want to tell you more about our web service: how it works and how we consume it via the app.

 

How our Twaddle web service works

 

As mentioned in our second blog post the mobile app connects to a servlet hosted by NW Cloud. This servlet acts like a web service: the app can ask for or send data and gets a response. To exchange the data between app and servlet we decided to use JSON. The great advantage of JSON is that its overload is very low (especially compared to XML) which is important in our mobile use case where we have to pay attention to exchange a small amount of data. The request-JSON is transported to the servlet via an HTTP-POST. The response-JSON is then returned to the app via the HTTP-response.

 

25-06-2012 15-46-49.jpg

 

Let’s take a deeper look in the syntax of our request- and response-JSON. Every request-JSON has to include a string parameter called function. In this parameter you specify the task of the web service: e.g. return all users or return messages for a given chat room. It’s also possible to use a function that creates resources, e.g. post a message or create a chat room. Depending on the function there have to be other parameters in the request-JSON. Nearly every function has to know for which user this function is called. By now the current user is a part of the request-JSON. That might be changed in the future when we got the authentication feature running. The response-JSON always includes the whole request-JSON. We enabled this functionality for debugging reasons; actually the app currently doesn’t need this parameter. Depending on the requested function the other parameters of the response-JSON can include e.g. a list of users or messages in a chat room.

 

How iOS talks to NW Cloud

For the communication between our iOS App and NW Cloud we are using post requests of the HTTP protocol. First of all we create a JSON with all the information the web service needs to give us the requested data back. There are a lot of free JSON classes you can use to create a JSON in Objective-C but we’re fine with those Apple provides. It’s basically the NSJSONSerialization Class.

 

We’ve created an NSDictionary object with all the information for the web service. The next step was to create a NSData Object with the help of NSJSONSerialization and the NSDictionary. As a last step we converted the NSData object into a NSString, which we need later for the HTTP post request.

 

// Creating JSON for HTTP post request

NSDictionary *dictJSONRequest = [NSDictionary dictionaryWithObjectsAndKeys:

                       @"getusers", @"function",

                       myuser, @"user", nil];

 

NSError *error;

NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictJsonRequest

                           options:NSJSONWritingPrettyPrinted error:&error];

NSString *resultAsString = [[NSString alloc] initWithData:jsonData

encoding:NSUTF8StringEncoding];

 

After that we created a NSMutableURLRequest with the URL of our servlet. We set the parameters for the post request and included the string of our JSON data.

 

// Creating URL of own servlet

NSURL *url = [[NSURL alloc] initWithString:@"https://twaddlep142549XXXXtrial.nwtrial.ondemand.com/Twaddle/"];

 

NSMutableURLRequest *request = [NSMutableURLRequest

                                  requestWithURL:tmpURL];

 

// Setting parameters for post request

NSString *params = [[NSString alloc] initWithFormat:@"post=%@", resultAsString];

[request setHTTPMethod:@"POST"];

[request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];

 

 

   

 

So all the preparatory work is almost done. After creating three more objects to manage the post request we sent a synchronous request with the help of NSURLConnection to our servlet. The response data is stored in a NSData object which can be converted into a NSString and later in a NSDictionary object so we can access to each keyword in the JSON response and work with the data.  With the help of the method “valueForKey” we can create a NSMutableArray with all the objects belonging to the keyword “users”.

 

NSData *data = nil;

NSError *error2 = nil;

NSHTTPURLResponse *response = NULL;

 

data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error2];

 

// do something with the data

NSLog(@"Succeeded! Received %d bytes of data",[data length]);

 

// Converting NSData Object into NSString

NSString *plainString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

 

NSError *e = nil;

 

// Creating NSDictionary object out of NSString - so you can access to each keyword in the JSON Response

NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&e];

 

NSMutableArray *allUsers = [jsonResponse valueForKey:@"users"];

 

 

 

Note: It’s also possible to send an asynchronous request to the servlet with the help of NSURLConnection. There is a Programming Guide from Apple regarding to this topic.

 

Servlet programming

The servlet has to parse the Post-Parameter as a JSON. To convert the JSON string into a Java object we use the library given on json.org because its license is unrestrictive.  When the parsing was successful the servlet checks the function-string to determine which procedure to start. All the data of the request-JSON is added to the response-JSON for debugging reasons.

 

// try to parse Post-parameter as JSON

try    {

       requestjson = new JSONObject(request.getParameter("post"));

}

catch(Exception e){

       throw new TwaddleException("Problems parsing request-string as JSON");

       }

 

// get function from request json

String function = requestjson.getString("function");

 

// add request-json to response-json for debugging reasons

responsejson.put("request",requestjson);

 

// depending on the function call special procedure

 

 

Here we will give you the example of our procedure for fetching all the users:

 

try    {

       EntityManager em = MainService.emf.createEntityManager();

       List<User> resultList = em.createQuery(

             "SELECT u FROM User u WHERE u.id <>'" +

             requestjson.getString("user").toUpperCase() + "'",

             User.class).getResultList();

            responsejson.put("success",true);

       HashMap<Object, Object> user;

// append all users to reponse-json

            for (User result : resultList)

             {

             user = new HashMap<Object, Object>();

             user.put("id", result.getId());

             user.put("name", result.getName());

                       responsejson.append("users",user);

             }

       }

catch (JSONException e) {

// Error-Handling

       }

// servlet returns the resonse-json

response.getWriter().write(responsejson.toString());

 

 

 

So these are basically the technics for our Twaddle web service. In our next blog post we want to focus on how we store the data on NW Cloud via JPA and also on the device via the CoreData framework to offer the user an offline view of our application. We always appreciate your feedback so please feel free to suggest any ideas of improvement.

Comments

Actions

Filter Blog

By author:
By date:
By tag: