2015/02/09
9 Feb, 2015

How to Write a Web Application Backed by WSO2 Middleware - Part 1

  • Hasitha Abeykoon
  • Associate Technical Lead - WSO2

Applies to

WSO2 Developer Studio Version 3.6.0
WSO2 Application Server Version 5.2.1
WSO2 Data Services Server Version 3.2.1


Table of contents

  1. Introduction
  2. What is a web application
  3. An hosting platform for web applications
  4. Writing a web application
    1. Designing front end pages
    2. Designing Back-end
      • Creating databases and tables
      • Exposing operations to above table as web services
      • Implementing servlets to call data services
      • Formatting results from the data service and passing it to the front-end
  5. How to compile and create a .WAR file
  6. How to deploy .WAR File on WSO2 Application Server
  7. How to test the web application
  8. Conclusion and possible improvements


Introduction

This article focuses on how to develop a simple web application using WSO2 Developer Studio as the coding environment. The main areas covered are as follows:

  • What is a web application
  • How to use developer studio to create a web app for WSO2 Application Server
  • How to create a data service and access within a web application
  • How to compile a web application
  • How to deploy a web app in WSO2 Application Server


What is a web application

A web application or web app is any application software that runs in a web browser or is created in a browser-supported programming language (such as the combination of JavaScript, HTML and CSS) and relies on a common web browser to render the application. Web applications are popular due to the ubiquity of web browsers, and the convenience of using a web browser as a client, sometimes called a thin client. The ability to update and maintain web applications without distributing and installing software on potentially thousands of client computers is a key reason for their popularity, as is the inherent support for cross-platform compatibility.


An hosting platform for web applications

Once a web application is written, in order to make it accessible via the World Wide Web, you need to host it in some server. There are open source and non-open source server software that can be used for this purpose[1]. For example:

  1. Apache Tomcat
  2. JBoss Application Server
  3. WSO2 Application Server

Some companies provide web hosting service. People can host their web applications on the cloud service and are charged by hosted time period or how many times accessed, etc. Following are some of such cloud services:

  1. Google App Engine
  2. CloudFoundry
  3. WSO2 App Factory

In this article, let us see how WSO2 Application Server can be used to host a web application.


Writing a web application

WSO2 Developer Studio is the tooling application in the WSO2 platform, which you can download from here. It has Eclipse based IDE. Let us use WSO2 Developer Studio to implement the web application.

  1. First navigate to File >> new >> other and select Dynamic web project.
  2. Figure 01


  3. Give a name for the project. Let us use the name “WSO2HealthWebApplication” and complete the wizard. This will create a folder structure for a typical web application as follows.
  4. Figure 02


    Designing front-end pages

  5. We need to define some theme for the web application. Every page in the web application will bear this theme. Having a theme for a web application is good as the user then gets the feeling that he/she is inside the web application.

    The theme is designed into the web pages inside the web application using CSS, images and javaScript. Let us first create a landing page for the web application with the theme. Inside WebContent folder, create a HTML page called landingPage.html. You can find the attached sources with the article.

    In order to create the theme, we use an image called all-in-one.png. Create a folder called images inside WebContent folder and copy the image there.

  6. Now we need to tell the web application the welcome page is the landingPage.html page we have designed. For this, insert the following entries to WEB-INF >> web.xml file.

      
      < welcome-file-list > 
        < welcome-file > landingPage.html < /welcome-file > 
      < welcome-file-list >
    
  7. As you might have noticed we have two links on the landing page. Those are for operations we are going to perform with the web application. As this is a simple patient management application, operations are:
    1. Add a patient to a database filling details of a patient (addPatient.jsp)
    2. Add a patient to a database filling details of a patient (addPatient.jsp)

    To perform these operations users need to input data using forms. Let us create two individual pages for the above two operations and then link them to the landingPage.html page we have just created (if you are referring to the attached source files those links are already there). For this, you need to copy addPatient.jsp file and getPatientDetails.jsp files into WebContent folder of the web application. You will notice the common theme we are using for this web application is on those pages as well.

    Following are the highlights of those two pages:

    1. addPatient.jsp
      • Has the title “Register New Patient”
      • Has a form to input patient number, last name, first name, contact number, city, street and country
      • The action of this form is “Register”
    2. addPatient.jsp
      • Has the title “Find Patient Details”
      • Has a form to input “patient ID” you want to query
      • The action of the form is “Search”
  8. Now the front end pages are ready. As soon as the web application is accessed, the user will be in the landing.html page and then depending on the link he/she clicks the user will either be in addPatient.jsp or getPatientDetails.jsp. We have not still discussed how are we going to show the query results on the latter case. Let us see how we can implement that later and now let us implement the back-end of the web application.


Designing back-end

In order to implement add patient and query patient operations, we need a database to store patient information. Furthermore, instead of directly dealing with the database within the application let us expose the patient information via web services and call them from our web application. This is the SOA way of implementing this functionality. The advantage of this is business logic, which is in the web application and is completely isolated from data management aspect.

This article divides the implementation of the back end to the following steps:

  1. Creating a database and a table to keep patient information
  2. Exposing operations to above table as web services
  3. Designing two servlets to call the above data services and do the necessary operations inside the web application
  4. Formatting results from the data service and passing it to the front-end in a presentable way

Each step is discussed in detail below.


Creating databases and tables

  1. First install MySQL for your machine. If you install MySQL WorkBench you can easily perform operations on MySQL via a UI.
  2. Create a database called “patientdb”.
  3. Create a table called “patient” with fields patientNumber, patientLastName, patientFirstName, phone, city, streetname, country.
  4. Insert some dummy patient data.

Executing following sql script you can get all above steps done.

DROP DATABASE IF EXISTS patientdb;

CREATE DATABASE patientdb;

GRANT ALL ON patientdb.* TO patientdb@'%' IDENTIFIED BY "patientdb";

GRANT ALL ON patientdb.* TO patientdb@'localhost' IDENTIFIED BY "patientdb";

USE patientdb;

DROP TABLE IF EXISTS patientdb;

CREATE TABLE patient(patientNumber INT, patientLastName VARCHAR(20), patientFirstName VARCHAR(20), phone VARCHAR(20), city VARCHAR(20), streetname VARCHAR(20), country VARCHAR(20));

INSERT INTO patient (patientNumber, patientLastName, patientFirstName, phone, city, streetname, country) VALUES (0001, "Amarasiri", "Evanthika", "+94773636352", "Galle Road", "Colombo 03", "Sri Lanka");

INSERT INTO patient (patientNumber, patientLastName, patientFirstName, phone, city, streetname, country) VALUES (0002, "Fernando", "Senaka", "+94777112987", "Je-ela", "Temple Road", "Sri Lanka");

INSERT INTO patient (patientNumber, patientLastName, patientFirstName, phone, city, streetname, country) VALUES (0003, "Hiranya", "Hasitha", "+94771222922", "Kandy", "Radella", "Sri Lanka");

INSERT INTO patient (patientNumber, patientLastName, patientFirstName, phone, city, streetname, country) VALUES (0004, "Madurangi", "Pavithra", "+94772331922", "Horana", "6th Street", "Sri Lanka");

INSERT INTO patient (patientNumber, patientLastName, patientFirstName, phone, city, streetname, country) VALUES (0005, "Anuradha", "Chamara", "+94773113871", "Kegalle", "5th Lane", "Sri Lanka");


Expose operations to the above table as web services

WSO2 has designed WSO2 Data Services Server to serve this purpose. You can manage, monitor, and design composite and complex database operations via web services using DSS.

  1. Download DSS from here and extract to a preferred location.
  2. We will offset the DSS server by 2. This will make all ports of the server to be offset by 2. Navigate to < DSS_Home >/repository/conf/carbon.xml file and edit < offset > tag to have 2.
  3. Go to /bin folder and start the server using

      Linux - sh wso2server.sh

    &nbps; Windows - wso2server.bat

  4. Login to the management console using default userName “admin” and default password “admin”.
  5. Go to main >> data service >> create

    Figure 03

    and create a data service called “WSO2HealthIT”

    Figure 04

  6. Add a new data source and save

    Figure 05

  7. Click next and now add a query called “registerPatientQuery”. We need to give field value mappings as query parameters as in the image below. There are no output mappings to this query (fire and forget).

    Figure 06

  8. Add another query called “patientDetailsByNumberSQL”. There is one input mapping to this query which is the patient number.

    Figure 07

    We have to define output mappings to suit patient information we want to receive as patient details. For example, we can map values in the table column “patientLastName” to the xml tag “patient-last-name” in the output result.

    Figure 08

    Figure 09

  9. Now click next and add the first operation called “registerPatient”. Select query ID “registerPatientQuery” as the query. Then it will automatically generate operation parameters. Operation parameter name will always be the xml tag name that DSS will be expecting on the payload. operation name will become the service name. Tick “Return Request Status” to get an output if the insert was a success or a failure.

    Figure 10

  10. Add another operation called “patientDetailsByNumber” and select “patientDetailsByNumberSQL” as the query ID.

    Figure 11

  11. Now click finish. Then after about 5 seconds refresh the services list and you should see WSO2HealthIT service deployed successfully.

  12. Click on “WSO2HealthIT" link and under “Client Operations” section click on “try this service”. Invoke the service and verify that it is working correctly before proceeding.

    Figure 12

Note: You can use WSO2HealthIT.dbs file to just perform all above steps. Go to data service >> upload and select the file and upload. Server will deploy the data service.


Implementing servlets to call data services

Now we have two working data services, namely “patientDetailsByNumber” and “registerPatient” services. From the web app we need to call these services and perform adding patients or querying patient information according to the input values to the forms. The way we do that is by submitting input values to a servlet and servlet carries out the java operations.

The servlet is a Java programming language class used to extend the capabilities of a server. They are commonly used to extend the applications hosted by web servers, so they can be thought of as Java applets that run on servers instead of in web browsers [2]. Servlets run in a servlet container that handles the networking side. In the example discussed in this article, WSO2 Application Server supplies the container for the web app.

  1. Create a package called org.wso2.sample inside “src” folder under “Java Resources”.
  2. We need to import libraries we need. Right click the WSO2HealthWebApplication project and select build path >> configure build path. Select “add external jars” under the libraries tab and import all the jar files attached under libs with this article.
  3. Copy attached QueryPatientDetailServlet.java, RegisterPatientServlet.java and Patient.java classes into the package created. Make sure there are no compilation errors in servlet classes.

It is important to note the following points on servlets.

  1. We grab the parameter values passes by jsp pages using request.getParameter("xxx”)

    String patientNumber = request.getParameter("patientNumber");

  2. We use axiom to create an OMElement to be set as the payload when calling the data service. The format of this payload should be identical to the payload template generated by “try it” functionality above. Please refer “createPayload()” methods of the servlets to understand how payload is created using Axiom.
  3. To send the payload message to the data service we use Apache Axis2.
    • Set an endpoint to the message - opt.setTo(new EndpointReference(dataServiceEP));
    • Set action - opt.setAction("urn:patientDetailsByNumber");
    • Send the payload and return the result - result = serviceclient.sendReceive(payload);
  4. Notice that if the HTTPS call succeeded, you get the response as an OMElement too. For example, when patient information is returned, they are returned to the servlet as a single OMElement. Using axiom we can extract needed information. If the HTTPS call was not successful, you will get an exception. In that case, information of the exception can be received and a custom message can be displayed on the same page as below.

      
    RequestDispatcher rd = getServletContext().getRequestDispatcher("/getPatientDetails.jsp");
    PrintWriter out= response.getWriter();
    out.println("Error While Quering Records : "+e.getMessage()+"");
    rd.include(request, response);
    
  5. We can redirect to web pages or forward the requests to pages using servlets.

      
    RequestDispatcher rd = getServletContext().getRequestDispatcher("/patientInfoPage.jsp");
    rd.forward(request, response);
    

    or

      
    res.sendRedirect("login.html");
    

    We should register servlets and url mappings in web.xml file.

      
    	<servlet> 
    		<servlet-name> Search </servlet-name>
    		<servlet-class> org.wso2.sample.QueryPatientDetailServlet </servlet-class> 
    	</servlet> 
    	<servlet> 
    		<servlet-name> Register </servlet-name> 
    		<servlet-class> org.wso2.sample.RegisterPatientServlet </servlet-class> 
    	</servlet> 
    	<servlet-mapping> 
    		<servlet-name> Search </servlet-name> 
    		<url-pattern> /Search </url-pattern> 
    	</servlet-mapping> 
    	<servlet-mapping> 
    	 <servlet-name>Register </servlet-name> 
    		<url-pattern>/Register </url-pattern> 
    	</servlet-mapping>
    

Note that we have hard coded DSS server URLs and ports inside the web application.


Format results from the data service and pass it to the front-end

If you inspect QueryPatientDetailServlet.java servlet you can see how information is extracted using axiom and how Patient objects are created out of the extracted information.

private List <Patient> parseResultFromDSS(OMElement response)

This list of patients is set as an attribute before forwarding to the patientInfoPage.jsp which renders patient information in a table.
request.setAttribute("patientList", patients);

At patientInfoPage.jsp page we traverse through the list which can be received as a session attribute.


		<table class="resultTable"> 
		<tbody>
		<tr>
			<th class= "a">First Name</th>
			<th class= "a">Last Name</th>
			<th class= "a">Phone Num</th>
			<th class= "a">Street</th>
			<th class= "a">City</th>
			<th class= "a">Country</th>
		</tr>
		<c:forEach items="${requestScope.patientList}" var="patientListVar">
		<tr>
			<td class= "a"><c:out value="${patientListVar.patientFirstName}"></c:out></td>
			<td class= "a"><c:out value="${patientListVar.patientLastName}"></c:out></td>
			<td class= "a"><c:out value="${patientListVar.phone}"></c:out></td>
			<td class= "a"><c:out value="${patientListVar.streetname}"></c:out></td>
			<td class= "a"><c:out value="${patientListVar.city}"></c:out></td>
			<td class= "a"><c:out value="${patientListVar.country}"></c:out></td>
		</tr>
		</c:forEach>
		</tbody>
		</table>

Thus, JSTL tags are helpful when you are dealing with a lot of data. You can find a well written article on how to use JSTL tags here.

Finally with all ingredients web application should be organized as follows.

Figue 13


How to compile and create a .war file

Now as the implementation of the web application is done, we need to create a deployable archive. The standard format to distribute a web application is .WAR (or Web application ARchive) format. Using WSO2 developer studio it is possible to create a .war file with a few clicks.

Right click WSO2HealthWebApplication project and select Export>> WAR file. It will compile the project and create the .war file


How to deploy .WAR file on WSO2 Application Server

  1. Download WSO2 application server from here and start it without a port offset (offset =0).
  2. Log in using default userName “admin” and password “admin”.
  3. Navigate to Manage >> Applications >> Add >> Web applications and upload the WSO2HealthWebApplication.war file.

    Figue 14

  4. Wait a short while until it gets deployed. Now if you go to Applications >> List , web application should appear there.

    Figue 15


How to test the web application

  1. Click on Go To URL. It will take you to the landing page of the web application.

    Figue 16

  2. Click on Register new patient. You will be navigated to addPatient page.

    Figue 17

    Fill in some valid information and click on register. If registered successfully, following confirmation page will be displayed.

    Figue 18

  3. Click “Home” link. It will redirect to landing page again. Now click on “Search Patient Records”.

    Figue 19

    You will see the search results like below.

    Figue 20


Conclusion and possible improvements

In this article we have discussed how to develop a simple web application that calls web services created using WSO2 middleware. Users can very easily develop the web application sitting on a single development platform provided by WSO2 Developer Studio rather than using an external IDE. Further, considering the steps discussed in the article, it is evident that the WSO2 middleware platform enables user to develop services and integrate them to custom applications with relatively a less number of steps compared to most other vendors.

The following improvements can be incorporated to the web application developed so far:

  1. Before taking to landing page, do an authentication using WSO2 Identity Server.
  2. Depending on role of the user allow registering patients and viewing patient information (authorization).
  3. Proxy the data service using WSO2 ESB and handle security within the ESB.
  4. Integrate WSO2 BAM for service monitoring.

In the next series of this article series we will see how to improve the web app including above improvements.


References

[1] https://en.wikipedia.org/wiki/Application_server

[2] https://docs.oracle.com/javaee/5/tutorial/doc/bnafe.html


Appendix

[1] https://wso2.com/files/How-to-write-a-web-apply-application-backed-by-wso2-middleware-01.zip

 

About Author

  • Hasitha Abeykoon
  • Associate Technical Lead
  • WSO2