SOAP at the moment is still the leading standard as it comes to web services. Only with mobile applications the usage and consumption of wsdl files take a lot of overhead. The wsdl files will get big and complex when services are getting bigger proportions. The usage of SOAP is not a standard feature in the android environment. I would like to keep the mobile application as small and standard as possible.
I wanted to connect a standard function module to android and not using SOAP? And that’s when I found a blog titled Real Web Services with REST and ICF by Dj Adams. With a quick and clear solution how to call web services via ICF. And the best thing about it is that it uses http and nothing else. Which of course is standard available in the android environment.
For this example I used a standard function module called DATE_GET_WEEK which will give the according week for the supplied date.
For making the function module available as a web service I used the ICF framework. You can create a new service by transaction SICF and adding a new sub-element. You have to define a handler element which will take care of the request. In my case I called it Z_CL_DATE_GET_WEEK.
Next step is creating the handler class which has to implement the interface IF_HTTP_EXTENSION. This will make the following method available in your class IF_HTTP_EXTENSION~HANDLE_REQUEST. To understand how to implement the method HANDLE_REQUEST. A brief explanation on how the URL handling works The URL I will be using to call the service will be similar to this. http://system:8000/sap/zrest/week_by_date/20101208.
This can be divided in:
Server and portnumber: system:8000
Namespace: sap
Service: zrest
Parameters to service: week_by_date, 20101208
In my example see code below. I ‘ll only be using the second parameter as a date string. By using the date string as the exporting param you can call the function module in reply you will get a week number back including the year. I'm not interested in the year so I will only return the week with the service. It’s an option to also put some error handling in the service.
Implementation of method HANDLE_REQUEST:
method IF_HTTP_EXTENSION~HANDLE_request.
* [DATA DEFINITION]
DATA:
path_info TYPE string,
verb TYPE string,
w_action TYPE string,
w_attr TYPE string,
w_body TYPE string,
gv_date TYPE datum,
gv_week TYPE kweek.
* [INTERPRET REQUEST]
path_info = server->request->get_header_field( name = '~path_info' ).
verb = server->request->get_header_field( name = '~request_method' ).
* (CHECK METHOD)
* Check if method is get.
IF verb NE 'GET'.
CALL METHOD server->response->set_header_field(
name = 'Allow' value = 'GET' ).
CALL METHOD server->response->set_status( code = '405' reason = 'Method not allowed' ).
EXIT.
ENDIF.
SHIFT path_info LEFT BY 1 PLACES.
SPLIT path_info AT '/' INTO w_action w_attr.
* (RETRIEVE DATA)
* Try to retrieve the week by input date.
gv_date = w_attr.
CALL FUNCTION 'DATE_GET_WEEK'
EXPORTING
date = gv_date
IMPORTING
week = gv_week
EXCEPTIONS
date_invalid = 1
OTHERS = 2.
* (NO VALID DATE OR OTHER ERROR OCCORRED)
* Abort with 404 if error
IF sy-subrc ne 0.
CALL METHOD server->response->set_status(
code = '404'
reason = 'ERROR' ).
CONCATENATE '' '' '' '' '' 'h1. ERROR with input param: ' w_attr ' ' '' '' INTO w_body.
CALL METHOD server->response->set_cdata( data = w_body ).
EXIT.
ENDIF.
* (STORE ATTRIBUTE)
w_body = gv_week+4(2). "We only need the last to characters for displaying the correct week.
* (SET CONTENT TYPE)
* Return attribute value in response body
CALL METHOD server->response->set_header_field(
name = 'Content-Type'
value = 'text/plain; charset=utf-8' ).
* (PUT DATA IN RESPONSE BODY)
CALL METHOD server->response->set_cdata( data = w_body ).
endmethod. "IF_HTTP_EXTENSION~HANDLE_REQUEST
This wraps up the back-end bit. But before using the service in android you can test the service in the browser by calling the URL. The result will look like this.
Note: Because I didn't change the default service settings you'll be prompted with a logon screen.
I developed the Android app in Eclipse. For more information on How to develop an android app click here. I’ll only explain how to call the web service in the android environment. You can call the web service via the org.apache.http.impl.client.DefaultHttpClient class which is standard provided in Android and actually is from the HTTP Components project of The Apache Software foundation. Because the service is using Basic Authentication it’s necessary to provide username and password to the DefaultHttpClient. The only problem is this is not by default supported in the HTTP Components project and is only available in the latest beta version. So for a quicker development I used this beta version. It's also an option to change the authentication settings of the service.
Implementation of the RESTService call
private String callRESTservice(String date) {
String result = "";
HttpHost targetHost = new HttpHost("saperp.ciberlabs.local", 8000, "http");
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.getCredentialsProvider().setCredentials(new AuthScope(targetHost.getHostName(), targetHost.getPort()), new UsernamePasswordCredentials(_username, _password));
// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate BASIC scheme object and add it to the local auth cache
BasicScheme basicAuth = new BasicScheme();
authCache.put(targetHost, basicAuth);
// Add AuthCache to the execution context
BasicHttpContext localcontext = new BasicHttpContext();
localcontext.setAttribute(ClientContext.AUTH_SCHEME_PREF, authCache);
HttpGet request = new HttpGet("/sap/zrest/test/" + date);
ResponseHandler<String> handler = new BasicResponseHandler();
try {
result = httpclient.execute(targetHost, request, handler);
} catch (ClientProtocolException e) {
e.printStackTrace();
result = "ClientException. The input was: " + date;
} catch (IOException e) {
e.printStackTrace();
result = "IOException. The input was: " + date;
}
httpclient.getConnectionManager().shutdown();
return result;
}
The DefaultHttpClient you provide the URL and the user credentials. After calling the execute function the week number will be returned.
When the application is called and you will click a button to execute the service. The following result will be displayed.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
36 | |
7 | |
5 | |
5 | |
5 | |
4 | |
4 | |
4 | |
3 | |
3 |