Android Chapter16 Web Services
Android Chapter16 Web Services
Victor Matos
Cleveland State University
Portions of this page are reproduced from work created and shared by Google and used according to terms
described in the Creative Commons 3.0 Attribution License.
Android & WebServices
Overview
• A WebService is a Consumer_Machine-to-Provider_Machine
collaboration schema that operates over a computer network.
Description WSDL (Web Service Desc. Lang) used for describing public
methods available from the endpoint
5
Android & WebServices
The Client Side - Consuming WebServices
There are two widely used forms of invoking and consuming WebServices:
https://www.google.com/search?q=cleveland+state+university
Figure 1. Example of a REST web-service called with a URL that includes arguments
7
Android & WebServices
REST vs. SOAP
Although SOAP and REST technologies accomplish the same final goal, that is
request and receive a service, there are various differences between them.
8
Android & WebServices
Figure 2. A WebClient consuming services using REST & SOAP
REST
Using common URL
Request
http://provider.org?op=function&
arg1=val1& arg2=val2 f1 (x1 ,..., xn1 )
Response ...
Free format. Options include: f m (x1 ,..., xkm )
Plain-text, HTML, XML, JSON… 9
Android & WebServices
Examples of Android Apps Using REST and SOAP
In the next sections we will present three examples showing how an Android
web-client typically interacts with a remote server requesting and consuming
WebServices.
References:
[1] http://msdn.microsoft.com/en-us/magazine/cc163647.aspx
[2] http://msdn.microsoft.com/en-us/library/ms734712(v=vs.110).aspx 11
Android & WebServices
WSDL Service Contracts
Example: The link http://www.webservicex.net/uszip.asmx?WSDL takes us to a WCF
EndPoint useful for finding locations in the US based on zip code (only a few lines are
shown). This view –written in WSDL- is known as the service contract.
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" ...
targetNamespace="http://www.webserviceX.NET">
<wsdl:types>
<s:schema elementFormDefault="qualified"
targetNamespace="http://www.webserviceX.NET">
Outgoing Envelop
(Request)
Incoming Envelop
(Response)
14
Android & WebServices
WSDL Service Contracts
Figure 5.
The Response data
is sent by the
WebService to
the client as an XML
encoded string.
15
Android & WebServices
Example1: Android SOAP Web-Client
This example consists of two parts. First we construct an EndPoint offering a
set of Windows IIS web-services, in the second part we build an Android
SOAP client that requests and consumes the previous web-services.
Client Side:
• We use the KSOAP 2.0 [1] library to send requests and receive results
to/from the IIS server.
• KSOAP offers various access methods such as: .getProperty(…),
.getPropertyAsString(…), .getPropertyCount() and so on, to dissect the
data tokens sent back in the composite response object.
17
Android & WebServices
Example1: KSOAP API
BACKGROUND KSOAP API
Android does not supply a native
SoapEnvelope
mechanism to handle SOAP Holds the encoded object’s head and
exchanges; therefore we have to body. Includes a parse() method to pull
use external software such as the the supplied XML data.
KSOAP API.
SoapObject
• KSOAP is a communication Generic container that travels inside the
support library designed for XML envelope transporting app’s data.
limited hardware devices. Custom objects must implement the
KvmSerializable interface.
• KSOAP can exchange simple HttpTransport
Java types (SoapPrimitive), as This method uses a URL to place an HTTP
well as serialized complex call and allow SOAP exchange using the
objects (SoapObject). JME generic connection framework.
19
Android & WebServices
Example1: A Sample of C#.NET Webservices Page 1 of 3
namespace WebServiceDemo1
{
1 [WebService(Namespace = "http://MyHostNameOrIPAddress/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[System.Web.Script.Services.ScriptService]
}//class
}//namespace
21
Android & WebServices
Example1: A Sample of C#.NET Webservices Page 3 of 3
namespace WebServiceDemo1
{
[Serializable]
3 public class Person
{
private string _personName;
private int _personAge;
public Person( String personNameValue, int personAgeValue )
{
this._personName = personNameValue; this._personAge = personAgeValue;
}
public Person( )
{
this._personName = "NA"; this._personAge = 0;
}
public string personName
{
get { return this._personName; }
set { this._personName = value; } There is an equivalent Java
} (POJO) version of this class in
public int personAge the Android’s app space.
{
get { return this._personAge; }
set { this._personAge = value; }
}
}
} 22
Android & WebServices
Example1: C# Webservices - Comments
1. Our IIS webservice is implemented in C#.Net; however any .NET language could
be used . The entry called Namespace identifies the IIS workspace hosting the
WebMethods to be called by the Android client app. The literal value of this
namespace is important as it will be referenced later by the client app as part of
its request object.
2. In our example the .NET service getPersonList accepts a string naming a location
(such as ‘Winterfel Castle’) and returns a list of its fictional inhabitants (Person
objects made according to the definition shown by Bullet 3). An answer encoded
in XML format is sent back to the client. For instance in our example, the returned
string is as follows (only a few lines are shown):
<ArrayOfPerson xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http:/
/www.w3.org/2001/XMLSchema-instance" xmlns="http://MyHostNameOrIPAddress/">
<Person>
<personName>Catelyn Stark</personName>
<personAge>40</personAge>
</Person>
<Person>
<personName>Sansa Stark</personName>
<personAge>14</personAge>
</Person>
</ArrayOfPerson> 23
Android & WebServices
Example1: C# Webservices - Comments
3. Important Note: Remember to modify the .NET application’s properties as
follows: On the ‘Solution Explorer’ look for the application, Right-Click >
Properties > Web > Use Local IIS server > Create Virtual Directory.
24
Android & WebServices
Example1: Android SOAP Web-Client + .NET Webservices
Figure 4. Android WebClient App
The figure shows the decoded response for the
request: getPersonList ( home) which returns a
partial list of the fictional inhabitants of a given
home location (eg. “Winterfel Castle”).
25
Android & WebServices
Example1: Android SOAP-Client Consuming .NET Webservices
public class SoapTestActivity extends Activity {
TextView result;
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_soap_test);
result = (TextView) findViewById(R.id.result);
26
Android & WebServices
Example1: Android SOAP-Client Consuming .NET Webservices
//do slow calls to remote server in a background thread
Thread slowJob = new Thread() {
@Override
public void run() {
// IP address at home
final String URL = "http://192.168.1.66/WebServiceDemo1/Service1.asmx";
final String NAMESPACE = "http://MyHostNameOrIPAddress/";
final String METHOD_NAME = "getPersonList";
String resultValue = "";
try {
2 //prepare SOAP REQUEST (namespace, method, arguments)
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
//passing primitive (simple) input parameters
request.addProperty("home", "Winterfel Castle");
//use KSOAP access methods to parse and extract data from response
for (int i = 0; i < response.getPropertyCount(); i++) {
resultValue += "\nRow-" + i;
resultValue += "\n\tKSOAP\n\t" + response.getProperty(i);
}
};
slowJob.start();
}// onCreate
29
Android & WebServices
Example1: Java Person Class & KSOAP Serialization
import org.ksoap2.serialization.SoapObject;
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
30
Android & WebServices
Example1: Android SOAP Client App - Comments
1. The Android webclient uses a background Thread to offload the task of
communicating with the (possibly slow) webserver while keeping the
app’s GUI responsive. Updates to the app’s GUI are made by the main
thread from the messages sent by the worker thread through a Handler
object.
2. The client prepares its request SoapObject indicating the Namespace
and WebMethod in that workspace that needs to be executed. Then,
each parameter (and its value) sent to the invoked method is added with
the .addProperty clause.
3. A SoapSerializationEnvelope is made to carry the user’s request to the
server. The envelope’s dotNet property indicates that it expects results
to be generated by the Windows server. The .addMapping method is
used to identify the Java type of the data returning inside the SOAP
envelope. In this example, the clause
new ArrayList<Person>().getClass()
tells the response consists of a list of user-defined Person objects.
31
Android & WebServices
Example1: Android SOAP Client App - Comments
4. The SOAP envelope is finally transported to the server designated by the
given URL. After that, the Android app waits for a response.
Java C#.NET
Person class XML string Person class
- name : String representing - PersonName : string
- age : int serialized object - PersonAge : int
33
Android & WebServices
Example 2:
Using an Android REST-based Client + PHP Webservices
In this second example an Android client uses REST protocol to interact with
an IIS server. WebServices in the Windows machine are implemented as a set
of PHP programs. We use JSON encoding for the client-server data exchange.
35
Android & WebServices
Example 2: PHP WebService – getPeopleNoSql.php (Version 1)
<?php
// METHOD: getPeopleNoSql.php
// retrieves people by castle location (eg.?castle=winterfel castle)
// data comes from comes from associative arrays (noSql)
// ----------------------------------------------------------------
// create anonymous Person-like objects
$person0 = array('name' => 'Daenerys Targaryen', 'age' => 18); The Person
$person1 = array('name' => 'Tiryion Lannister', 'age' => 30); dataset is
$person2 = array('name' => 'Arya Stark', 'age' => 11);
$person3 = array('name' => 'Jon Snow', 'age' => 20);
retrieved
$person4 = array('name' => 'Hodor', 'age' => 40); from a PHP
associative
// create lists of people-by-HomeCastle array
$winterfelPeople = array($person2, $person3,$person4);
$otherPeople = array($person0, $person1);
$personList = array();
$i = 0;
while (mysqli_stmt_fetch($stmt)) {
$person = array( 'name' => $name, 'age' => $age
);
$personList[]=$person; The Person
} dataset is
// close prepared statement, connection retrieved
mysqli_stmt_close($stmt);
mysqli_close($link); from a
3 MySQL
//respond with encoded person-list database
$jsondata = json_encode($personList);
echo $jsondata;
?> 38
Android & WebServices
Example 2: MySQL Database
Example based on characters from
HBO Series - Game of Thrones ©
by G. R.R. Martin
http://www.hbo.com/game-of-thrones#/game-of-thrones
} catch (Exception e) {
Log.e("Error-Background", e.getMessage());
} finally {
try {
responseBuffer.close();
} catch (Exception e) {
Log.e("Closing-Background", e.getMessage());
}
}
return null; // needed to gracefully terminate Void method
}
43
Android & WebServices
Example 2: Android REST-based Client cont. 4
try {
dialog.dismiss();
// update GUI with JSON Response
txtResponseJson.setText(jsonResponse);
} catch (Exception e) {
Log.e("PARSING", e.getMessage());
}
txtResponseJava.append( result );
} catch (JsonSyntaxException e) {
Log.e("POST-Execute", e.getMessage() );
}
}
}//asyncktask
}//class 45
Android & WebServices
Example 2: Android REST-based Client - Comments
1. The client app uses an AsyncTask object to call the remote WebService. This
practice is functionally equivalent to running a background thread but offers
more options (such as showing progress messages).
2. doInBackground takes the supplied URL to reach the server and request its
assistance. The org.apache.http.client.HttpClient class is responsible for
establishing the asynchronous HTTP client-server exchange. In our example
an HTTP GET operation is invoked using the URL:
http://192.168.1.66/gameofthrones/getPersonMySql.php?castle=King's+Landing
the called PHP method getPersonMySQL extracts its result from a MySql
database. Observe that URL arguments appear after the ? symbol. You may
also replace spaces with + symbols as in castle=King’s+Landing
3. The client app collects the JSON encoded result in a StringBuilder. In our
example the returned string is: [{"name":"Tiryion Lannister",
"age":30},{"name":"Cersei Baratheon","age":32}]
HTTPClient Ref: 46
http://developer.android.com/reference/android/net/http/AndroidHttpClient.html
Android & WebServices
Example 2: Android REST-based Client - Comments
4. The onPostExecute portion of the AsyncTask decodes the JSON response
string into a Java ArrayList<Person> collection.
We have chosen Google’s GSON API for processing the incoming JSON
string. The example shows two approaches for decoding JSON data:
(a) The first invokes the fromJson(data, type) method,
(b) the second alternative parses the JSON string looking for the
occurrence of JsonElement, JsonArray, and JsonObject tokens.
47
Android & WebServices
Example 3: Android REST consuming ServLet Webservices
This problem is similar to Example-2. An Android REST-based client supplies a location
and a webservice retrieves all inhabitants of that place.
As before we divide the problem in two parts, first we discuss step-by-step how to
create the Tomcat hosted Servlet, then we build an Android client using REST to
communicate with it.
Reference:
http://download.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html
49
Android & WebServices
Example 3: Create a ServLet
We assume you are using Eclipse EE and Apache Tomcat 7.0 (or newer).
3. Place inside the package a new Servlet. In the ‘Class name’ box enter: GetHeroes.
Click the button ‘Finish’.
http://localhost:8080/GameOfThrones/GetHeroes?castle=dragonstone
52
Android & WebServices
Example 3: Create a ServLet
context.xml
This file indicates how to connect to a MySql database. It includes the user’s name,
password, driver name, connection parameters, and database connection string.
It must be placed in the WebContent/META-INF/ folder.
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<!-- comments removed -->
<Resource name="jdbc/mysqlresourcegameofthrones"
auth="Container"
type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000"
username="csuperson"
password="euclid"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://192.168.1.66:3306/gameofthrones"/>
</Context>
53
Android & WebServices
Example 3: Create a ServLet 1 of 2
web.xml
This file lists the parts of the servlet, its resources, and indicates how to map the
Servlet’s java classes to webService names passed in the request object. It must be
placed in the WebContent/WEB-INF folder.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-
app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>GameOfThrones</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
</welcome-file-list>
<servlet>
<description></description>
<display-name>GetHeroes</display-name>
<servlet-name>GetHeroes</servlet-name>
<servlet-class>csu.matos.GetHeroes</servlet-class>
</servlet>
54
Android & WebServices
Example 3: Create a ServLet 2 of 2
web.xml cont.
<servlet-mapping>
<servlet-name>GetHeroes</servlet-name>
<url-pattern>/GetHeroes</url-pattern>
</servlet-mapping>
<resource-ref>
<description>MySQL Datasource – GameOfThrones Example</description>
<res-ref-name>jdbc/mysqlresourcegameofthrones</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
55
Android & WebServices
Example 3: Create a ServLet - GetHeroes Servlet 1 of 5
GetHeores is the actual servlet. It does all its work inside the doGet method. The
incoming request string is examined looking for the argument=value pairs it may carry.
Once the castle value is know a list of its associated people is assembled. The servlet
redundantly extracts its data from two sources, first it uses an in-memory collection of
datasets, then it repeats the same type of retrieval querying a mySql database.
@WebServlet("/GetHeroes")
public class GetHeroes extends HttpServlet {
private static final long serialVersionUID = 1L;
1
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter output = response.getWriter();
output.println(" [0] NEW TEST: " + new Date());
} else if ("dragonstone".startsWith(castle)) {
peopleResult = dragonPeople;
@Override
protected void doPost( HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
// Retrieve designated people this time from a mySql database
private ArrayList<Person> getDbRecord(String castle) throws Exception {
java.sql.ResultSet rs = stm.executeQuery(mySQL); 59
Android & WebServices
Example 3: Create a ServLet - GetHeroes Servlet 5 of 5
7 while ( rs.next() ){
String pname = rs.getString("name");
int page = Integer.parseInt(rs.getString("age"));
String pcastle = rs.getString("castle");
Person pers = new Person(pname, page, pcastle);
result.add(pers);
}
}
catch (java.sql.SQLException e) {
throw new Exception (" [*[Problems1 ]*] " + e.getMessage());
} catch (javax.naming.NamingException e) {
throw new Exception ( " [*[Problems2 ]*] " + e.getMessage());
}
return result;
}//getDbRecord
}// class
60
Android & WebServices
Example 3: Create a ServLet - Person class
public class Person {
8
private String name;
private int age;
private String castle;
public Person() {
this.name = "na"; this.age = -1; this.castle = "na";
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", castle=" + castle + "]";
}
}
61
Android & WebServices
Example 3: ServLet - Comments
1. This servlet only implements its doGet method in which a request URL string is
accepted and a response object is sent back to the caller.
2. For demonstration purposes the servlet returns twice the result-set. First data is
selected from an in-memory (ArrayList-based) collection, the second time data
comes from a relational database.
3. The incoming castle argument is extracted from the request URL, it indicates
what group of people should be retrieved.
4. After a resultset consisting of Person objects held in an ArrayList is assembled,
the collection is converted to a JSON string (we use GSON library, see Lecture 14).
5. The method getDbRecord redundantly retrieves a version of the resultset from a
MySql database. DataSource specs for reaching the database are taken from the
global server’s contex file.
6. A select-statement adds the castle argument to its where clause to find the tuples
satisfying the search condition.
7. Database rows are scanned one at the time. From each selected tuple a Person
object is created and added to a growing ArrayList. After all rows are processed
the ArrayList is returned.
62
Android & WebServices
Example 3: Transfer your Servlet to the Production Server
Eclipse Workspace Tomcat Server
63
Android & WebServices
Example 3: Transfer your Servlet to the Production Server
Preliminary Steps
• Stop the Eclipse Tomcat server instance (no other webserver should be running).
• Locate the Tomcat production server in your system ( usually at c:\Program
Files\Apache Software Foundation\Tomcat 7.0 ). If needed create a folder called
/webapps/GameOfThrones. Add The subdirectories META-INF and WEB-INF.
Transfer Files From Eclipse Workspace to the Tomcat Production Server
1. Modify the production server’s file \conf\context.xml. Add to it a copy of the
<resource… /> XML entry from your Eclipse WebContent\META-INF\context.xml
file. Observe that you may end-up with more than one global <resource> entry.
2. Use your Windows Explorer to find and copy the Eclipse’s build\classes folder.
Paste this copy in the server’s webapps\GameOfThrone\WEB-INF\ folder.
3. Copy each of the jars used by the servlet into the server’s \lib\ folder.
http://localhost:8080/GameOfThrones/GetHeroes?castle=winterfel
65
Android & WebServices
Example 3: Android Client
Use the same Android client from the previous example. Change the URL to the
desired destination. For this example, test the client-app with the URL values:
http://localhost:8080/GameOfThrones/GetHeroes?castle=winterfel
http://localhost:8080/GameOfThrones/GetHeroes?castle=king’s+landing
http://localhost:8080/GameOfThrones/GetHeroes?castle=dragonstone
66
Producing & Consuming Web Services
67
Appendix A. Connecting to Oracle DBMS
REST Protocol – Android & Apache's Tomcat Server
This relaces Step 8 in Example 2C. Multitier Application
Add the following DataSource to the application’s context.xml file. Add the file to the
/WebControl/META-INF/ folder of your Eclipse workspace solution (later, this
fragment will be copied to the Tomcat’s /conf/context.xml file)
</context>