One
of the most common functionalities required in mobile applications is to call a
web service to retrieve data. This process involves requesting the web service
with parameters, receiving the response and parsing it to obtain
data.
Today the most common web services types
are SOAP and REST. Android does
not provide a built in SOAP client, there are many third party libraries that
can be used, but we’ll see how to call a SOAP web service with native android APIs.
Requesting SOAP web service:
Before proceeding to the code, let’s take a
look at the SOAP structure:
A soap request can be something like this:
Host: www.example.org
Content-Type:
application/soap+xml; charset=utf-8
Content-Length: length
SOAPAction:
"http://www.w3schools.com/GetItems"
<?xml
version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Header>
<m:Trans
xmlns:m="http://www.w3schools.com/transaction/"
soap:mustUnderstand="1">234
</m:Trans>
</soap:Header>
<soap:Body>
<m:GetPrice
xmlns:m="http://www.w3schools.com/prices">
<m:Item>Apples</m:Item>
</m:GetPrice>
</soap:Body></soap:Envelope>
The SOAP request/response is sent as a SOAP Envelope which consists of a SOAP Header and a SOAP Body.
1.
SOAP
Header: optional
component of the envelop, contains application specific information, such
as authentication.
2.
SOAP
Body: the actual
message sent to/received from the service.
3.
The header can contain
a SOAP Action which identifies the desired function
to be called by the service.
Calling the service:
To
call the SOAP web service you have to do the following:
First: construct the SOAP envelope manually like this:
String
envelope="<?xml version=\"1.0\"
encoding=\"utf-8\"?>"+
"<soap:Envelope
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"
xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"+
"<soap:Body>"+
"<GetItems
xmlns=\"http://tempuri.org/\">"+
"<startDate>%s</
startDate>"+
"<getAll>%s</getAll>"+
"</Items>"+
"</soap:Body>"+
"</soap:Envelope>";
where %s are place
holders where you substitute request parameters in like this
String
requestEnvelope=String.format(envelope,
"10-5-2011","true");
Second: call the web service like this:
Second: call the web service like this:
String
CallWebService(String url,
String soapAction,
String envelope) {
final DefaultHttpClient httpClient=new
DefaultHttpClient();
// request parameters
HttpParams params = httpClient.getParams();
HttpConnectionParams.setConnectionTimeout(params, 10000);
HttpConnectionParams.setSoTimeout(params,
15000);
// set parameter
HttpProtocolParams.setUseExpectContinue(httpClient.getParams(), true);
// POST the envelope
HttpPost httppost = new HttpPost(url);
// add headers
httppost.setHeader("soapaction",
soapAction);
httppost.setHeader("Content-Type", "text/xml;
charset=utf-8");
String responseString="";
try {
// the entity holds the request
HttpEntity entity = new
StringEntity(envelope);
httppost.setEntity(entity);
// Response handler
ResponseHandler<string> rh=new
ResponseHandler<string>() {
// invoked when client receives response
public String handleResponse(HttpResponse
response)
throws ClientProtocolException,
IOException {
// get response entity
HttpEntity entity = response.getEntity();
// read the response as byte array
StringBuffer out = new
StringBuffer();
byte[] b =
EntityUtils.toByteArray(entity);
// write the response byte array to
a string buffer
out.append(new String(b, 0,
b.length));
return out.toString();
}
};
responseString=httpClient.execute(httppost,
rh);
}
catch (Exception e) {
Log.v("exception",
e.toString());
}
// close the connection
httpClient.getConnectionManager().shutdown();
return responseString;
}
After calling this function, you will have the
response as a String, something like this:
<?xml
version="1.0" encoding="utf-8"?>
<soap:Envelope
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetItemsResponse
xmlns="http://tempuri.org/">
<GetItemsResult>
<Items>
<Item>
<name>string</name>
<description>string</
description >
</iPhoneCategory>
<iPhoneCategory>
<name>string</name>
<description>string</
description >
</ Item >
</Items>
</GetItemsResult>
</ GetItemsResponse >
</soap:Body>
</soap:Envelope>
This response needs to be parsed to extract
the data.
Requesting REST web service:
REST web services are much simpler, you
request the service by calling a URL with the parameters. like this
http://example.com/resources/getitems
an example of calling a REST web service:
String
callWebErvice(String serviceURL){
// http get client
HttpClient client=new
DefaultHttpClient();
HttpGet getRequest=new HttpGet();
try {
// construct a URI object
getRequest.setURI(new URI(serviceURL));
} catch (URISyntaxException e) {
Log.e("URISyntaxException",
e.toString());
}
// buffer reader to read the response
BufferedReader in=null;
// the service response
HttpResponse response=null;
try {
// execute the request
response = client.execute(getRequest);
} catch (ClientProtocolException e) {
Log.e("ClientProtocolException",
e.toString());
} catch (IOException e) {
Log.e("IO exception",
e.toString());
}
try {
in=new BufferedReader(new
InputStreamReader(response.getEntity().getContent()));
} catch (IllegalStateException e) {
Log.e("IllegalStateException",
e.toString());
} catch (IOException e) {
Log.e("IO exception",
e.toString());
}
StringBuffer buff=new
StringBuffer("");
String line="";
try {
while((line=in.readLine())!=null)
{
buff.append(line);
}
} catch (IOException e) {
Log.e("IO exception",
e.toString());
return e.getMessage();
}
try {
in.close();
} catch (IOException e) {
Log.e("IO exception",
e.toString());
}
// response, need to be parsed
return buff.toString();
}
Connecting to a web service over a Secure Sockets Layer (SSL):
protocol:
Android
default HttpClinet does not support SSL connections, so if
you have a secured web service, you need to connect to it via javax.net.ssl.HttpsURLConnection.
if you want to call a SSL SOAP web service:
String
CallWebService(String url,
String soapAction,
String envelope) throws IOException {
URL address=new URL(url);
URLConnection
connection=address.openConnection();
HttpsURLConnection
post=(HttpsURLConnection)connection;
post.setDoInput(true);
post.setDoOutput(true);
post.setRequestMethod("POST");
post.setRequestProperty("SOAPAction", soapAction);
post.setRequestProperty(
"Content-type", "text/xml; charset=utf-8" );
post.setRequestProperty(
"Content-Length", String.valueOf(envelope.length()));
post.setReadTimeout(4000);
OutputStream
outStream=post.getOutputStream();
Writer out=new OutputStreamWriter(outStream);
out.write(envelope);
out.flush();
out.close();
InputStream inStream = post.getInputStream();
BufferedInputStream in = new
BufferedInputStream(inStream,4);
StringBuffer buffer=new StringBuffer();
// read 4 bytes a time
byte[] buffArray=new byte[4];
int c=0;
while((c=in.read(buffArray))!=-1){
for(int i=0;i<c;i++)
buffer.append((char)buffArray[i]);
}
return buffer.toString();
}
In this post we saw how to request a web
service, in the next post we’re going to see how to parser the different (SOAP,
XML, JSon) types of responses.
Hi Pavan,
ReplyDeleteThis is very useful post for Android developers.
Thank you very much for this post.