You are on page 1of 27

J.E.D.I.

J2ME and Enterprise Computing

.1 Objectives

In this section, we will be learning how to write Servlets, use JSP and JSTL, access a
database using JDBC and create and parse XML documents.

After finishing this lesson, the student should be able to:

• write simple Servlets


• write simple JavaServer Pages (JSP) using JSTL
• write JSTL code using Expression Language (EL)
• access a database using JDBC
• generate XML
• parse the XML on the Mobile client

.2 Servlets

A servlet is a server-side Java class for implementing a request-response type


transaction. With servlets, Java provides a better and portable alternative to CGI
(Common Gateway Interface) scripts. Compared to CGI scripts (written in Perl, sheel
scripts, or other scripting languages), Java servlets provide a scalable, platform
dependent technology that deliver dynamic content.

A servlet has two methods for processing a request, the doGet() and doPost() methods.
These methods are called when the web client (browser) issues a "GET" or "POST"
command. These methods have identical parameters. These parameters are normally
handed off to a common method so that both GET and POST request are handled the
same way.

protected void doGet(


HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// process request ...
}

protected void doPost(


HttpServletRequest request,

Mobile Application Development 1


J.E.D.I.

HttpServletResponse response)
throws ServletException, IOException {

// process request ...


}

import java.io.*;
import java.net.*;

import javax.servlet.*;
import javax.servlet.http.*;

public class SampleServlet extends HttpServlet {

protected void processRequest(


HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();

out.println("<html>");
out.println("<head>");
out.println("<title>Servlet SampleServlet</title>");
out.println("</head>");
out.println("<body>");

out.println("<h1>Servlet SampleServlet at "


+ request.getContextPath () + "</h1>");
out.println("</body>");
out.println("</html>");

out.close();
}

protected void doGet(


HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

processRequest(request, response);

Mobile Application Development 2


J.E.D.I.

protected void doPost(


HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

processRequest(request, response);
}

/** Returns a short description of the servlet.


*/
public String getServletInfo() {
return "Short description";
}
}

Mobile Application Development 3


J.E.D.I.

To create a new Web Project, click File -> New Project... ->Web: Web Application. Select
and input a name for your project and click finish.

Mobile Application Development 4


J.E.D.I.

To create a new Servlet, click on File -> New File.. -> Web: Servlet

Mobile Application Development 5


J.E.D.I.

.3 JSP/JSTL

The primary goal of the JavaServer Pages Standard Tag Library (JSTL) is to help authors
simplify scripting on JSP pages. JSTL briges the gap between programmers and (non-
programmer) page authors by providing a simple expression language for JSP pages.

Aside from the expression language support actions and crontrol flow actions, JSTL also
provides functionality for accessing URL-based resources, internationalization and
number and date formatting, database access and XML processing.

JTSL is composed of several tag libraries, grouped by functional area.

Area Prefix URI Example code snippet

core c http://java.sun.com/jstl/core <c:out value="${var}"/>

I18N formatting fmt http://java.sun.com/jstl/fmt <fmt:formatNumber

XML processing x http://java.sun.com/jstl/xml <x:forEach ...

Database (SQL) sql http://java.sun.com/jstl/sql <sql:query var=...

Functions fn http://java.sun.com/jstl/functions <fn:

In this section, we will be discussing the core tag library.

.3.1 Configuration

To be able to use JSTL tags, the taglib directive should be included in the JSP page, one
each for every functional area that will be used in that page.

<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>

You should also include the jstl.jar into your project's library folder:

1. Right click on the Libraries folder of your project and select "Add Library" from the

Mobile Application Development 6


J.E.D.I.

pop-up menu:

2. Select "JSTL 1.1" and click "Add Library". "JSTL 1.1 – standard.jar" and "STL
1.1 – jstl.jar" would be added to your projects library.

Mobile Application Development 7


J.E.D.I.

.3.2 Hello, world!

A JSP page is just an HTML page with codes and/or tags. Here is a very minimal JSP
page. Save this code snippet to hello.jsp under the Web Pages directory, right click on
the filename and choose "Run File" to display the output of this JSP page in your web
browser:

<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>

<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"


"http://www.w3.org/TR/html4/loose.dtd">

<c:set var="message" value="hello, world!"/>


<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><c:out value="${message}"/></title>
</head>
<body>

<h1><c:out value="${message}"/></h1>

</body>
</html>

Mobile Application Development 8


J.E.D.I.

.3.3 Transferring control from Servlet to JSP

import java.io.*;
import java.net.*;

import javax.servlet.*;
import javax.servlet.http.*;

public class SampleServlet2 extends HttpServlet {

/** Processes requests for both HTTP <code>GET</code>


* and <code>POST</code> methods.
* @param request servlet request
* @param response servlet response
*/
protected void processRequest(
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {

String[] days = {"Sunday", "Monday", "Tuesday", "Wednesday"};


request.setAttribute("days", days);
request.setAttribute("message", "hello, world!");

RequestDispatcher dispatcher = request.


getRequestDispatcher("/control.jsp");

Mobile Application Development 9


J.E.D.I.

// transfer control to JSP page


if (dispatcher != null)
dispatcher.forward(request, response);
}

/** Handles the HTTP <code>GET</code> method.


* @param request servlet request
* @param response servlet response
*/
protected void doGet(
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {

processRequest(request, response);
}

/** Handles the HTTP <code>POST</code> method.


* @param request servlet request
* @param response servlet response
*/
protected void doPost(
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {

processRequest(request, response);
}

/** Returns a short description of the servlet.


*/
public String getServletInfo() {
return "Short description";
}
}

Mobile Application Development 10


J.E.D.I.

.3.4 Expression Language

.3.4.1 Accessing Variables, Properties and Collections

In order to access a variable, the syntax is: ${var}

Example: output the value of the variable username

<c:out value="${username}"/>

JSTL unifies access to Java bean properties and collection values. The expression
varX.varY is equivalent to varX[varY] in JSTL. The expression varX.varY (or varX[varY])
would evaluate depending on the type of varX:

1. If varX is a JavaBean: varY would be converted to String. If varY is a readable


property of varX, it would return the result of the getter call: varX.getVarY()
2. If varX is a List: varY is coerced to int. Evaluates to: varX.get(varY)
3. If varX is an array: varY is coerced to int. Evaluates to: Array.get(varX, varY)
4. If varX is a Map: Evaluates to: varX.get(varY)

Variables can have page, request, session and application scope. The expression

Mobile Application Development 11


J.E.D.I.

language would look for the identifier in these scopes. If the identifier is not found, null
is returned.

.3.4.2 Implicit Objects

JSTL automatically initializes several Map variables with values from different sources.
These variables are available to the JSP pages without any initialization from the user.
For example, the variable param contains mappings of parameters' names and values
from the request. These names and values (param) are from HTML form submissions
submitted either via HTTP GET or POST methods.

Implicit Object Contents

pageScope a Map containing a mapping of page-


scoped attibute names to their values

requestScope a Map containing a mapping of request-


scoped attibute names to their values

sessionScope a Map containing a mapping of session-


scoped attibute names to their values

applicationScope a Map containing a mapping of application-


scoped attibute names to their values

param a Map containing a mapping of parameter


names to its parameter value (String).
equivalent to
ServletRequst.getParameter(String)

header a Map containing a mapping of header


names to a its value (String). Equivalent to
ServletRequst.getHeader(String)

cookie a Map containing a mapping of cookie


names to their cookie values. Equivalent to
HttpServletRequest.getCookie(String)

.3.4.3 Operators

The JSTL Expression Language (EL) supports relational, arithmetic and logical operators.

The supported relational operators are:


• == (or eq)
• != (or ne)
• < (or lt)
• > (or gt)

Mobile Application Development 12


J.E.D.I.

• <= (or le)


• >= (or ge)

The logical operators are:


• && (or and)
• || or (or)
• ! (or not)

And the arithmetic operators of EL are:


• + (addition)
• - (subtraction)
• * (multiplication)
• / (division)
• % or mod (remainder or modulus)

The additional empty operator is very useful for testing null or empty values.

<c:if test="${empty param.username}">No username</c:if>

.3.4.4 Exceptions and Default Values

To simplify JSP pages, simple errors will not generate exceptions. Displaying a variable
with a null value will simply display "(null)" instead of generating a
NullPointerException.

Username: <input
type="text"
value="<c:out value="${param.username}"/>"
name="username" />

Undefined variables used in expressions take 0 (zero) as their default value. This
expression would evaluate to 1 if the parameter "start" is not set:

<c:out value="${param.start + 1}"/>

.3.5 core tag library

Mobile Application Development 13


J.E.D.I.

.3.5.1 c:out

The c:out tag evaluates an expression and outputs its result.

Syntax:

<c:out
  value="value"
  [escapeXml="{true|false}"]
  [default="defaultValue"]
/>

Name Dynamic Required Type Description

value yes yes Object The expression to be evaluated

escapeXml yes no boolean If true, the characters <, >, &, ' and "
are converted to their character entity
codes (eg: > converts to &gt;). Default
value is true.

default yes no Object The default value if the result value is


null

Examples:

Rows: <c:out value="${param.numRows}" defaultValue="20" />

Description:
<pre>
<c:out value="${bookmark.description}" escapeXml="false" />
</pre>

.3.5.2 c:set

Sets the value of a (scoped) variable.

Syntax:

<c:set
value="value"
var="varName"

Mobile Application Development 14


J.E.D.I.

[scope="{page|request|session|application}"]
/>

Name Dynamic Required Type Description

value yes yes Object The expression to be evaluated

var no yes String The name of the exported variable that


will hold the value of the expression. The
type of the variable follows the type of
the result of the expression

scope no no String The scope of var

Example:

<c:set var="fullName" value="${lastName, firstName}" />

.3.5.3 c:remove

Removes (undefines) a (scoped) variable

Syntax:

<c:remove
  var="varName"
  [scope="{page|request|session|application}"]
/>

Name Dynamic Required Type Description

var no yes String The name of the variable to be deleted

scope no no String The scope of var

Example:

<c:remove var="tempVar" scope="session" />

.3.5.4 c:if

Conditional evaluation. Will process the body content if the test condition evaluates to
true.

Mobile Application Development 15


J.E.D.I.

Syntax:

<c:if test="testCondition"
  [var="varName"] [scope="{page|request|session|application}"]>
body content
</c:if>

or

<c:if test="testCondition"
  var="varName" [scope="{page|request|session|application}"]
/>

Name Dynamic Required Type Description

test yes yes boolean The test condition that determines if the
body content should be processed.

var no no/yes String The name of the exported variable that


will hold the value of the test condition.
The type of the scoped variable is
Boolean.

scope no no String The scope of var

Example:

<c:if test="${empty param.username}">No username</c:if>

.3.5.5 c:choose, c:when, c:otherwise

The c:choose is like the Java switch statement, providing a mutually exclusive
conditional execution. The body content of c:otherwise (if it exists) will be evaluated if
no when statement evaluates to true. The otherwise block must be the last in the choose
statement (cannot be followed by another c:when). It must also be preceded by at least
one c:when statement.

Syntax:

<c:choose>

<c:when test="condition">
body content
</c:when>

Mobile Application Development 16


J.E.D.I.

<c:when test="condition">
body content
</c:when>...
]

[
<c:otherwise>
body content
</c:otherwise>
]

</c:choose>

Name Dynamic Required Type Description

test yes yes boolean The test condition that determines if the
body content should be processed.

Example:

<c:choose>
<c:when test="${gender eq 'M'}">Male</c:when>
<c:when test="${gender eq 'F'}">Female</c:when>
<c:otherwise>Unknown</c:otherwise>
</c:choose>

.3.5.6 c:forEach

c:forEach iterates over the contents of a collection. The collection can be any of the
subclasses of java.util.Collection and java.util.Map. Arrays of objects and primitive types
are also supported. A String of comma separated values ("True,False") can also be used
for the iteration. As long as there are items in the collection, the body content is
processed.

c:forEach can also be used to iterated for a fixed number of times.

The varStatus is of type javax.servlet.jsp.jstl.core.LoopTagStatus.  It has the


properties index (index of the current iteration, zero-based) and count (the count of the
current iteration, one-based, eg. if the begin index is 20, the end index is 80 and the
step is 10, the count would be 1,2,3,4,5,6,7). The boolean properties first and last
denote if the currrent iteration is the first or last, respectively. There are also the begin,
end and step properties which hold the values of the begin, end and step parameters of
the c:forEach loop.

Syntax:

Mobile Application Development 17


J.E.D.I.

<c:forEach
  [var="varName"]
  items="collection"
  [varStatus="varStatusName"]
  [begin="begin"] [end="end"] [step="step"]
>

body content

</c:forEach>

or

<c:forEach [var="varName"]
  [varStatus="varStatusName"]
  begin="begin" end="end" [step="step"]
>

body content

</c:forEach>

Name Dynamic Required Type Description

var no no varies The name of the exported variable for


every content of the collection.

items yes yes/no Collection, Collection of items to iterate over


Map, Array,
String

varStatus no no String The name of the exported variable for the


status of the operation. The object
exported is of type
javax.servlet.jsp.jstl.core.LoopTagS
tatus

begin yes no/yes int beginning index (zero-based) in the items,


or a fixed beginning index (if no items is
specified)

end yes no/yes int end index (zero-based) in the items, or a


fixed end index (if no items is specified)

step yes no int The loop will only process every "step"
items of the iteration, starting with the
first one

Example:

<select name="gender">
<c:forEach var="gender" items="${genderList}">
<option value="<c:out value="${gender.code}"/>">
<c:out value="${gender.name}"/>

Mobile Application Development 18


J.E.D.I.

</option>
</c:forEach>
</table>

.3.5.7 c:forTokens

c:forTokens iterates over the tokens (separated by a delimiter) in a String.

Syntax:

<c:forTokens
  items="stringOfTokens"
  delims="delimiters"
  [var="varName"]
  [varStatus="varStatusName"]
  [begin="begin"] [end="end"] [step="step"]
>

body content

</c:forTokens >

Name Dynamic Required Type Description

var no no varies The name of the exported variable for


every iteration/token

items yes yes String String of tokens

delims yes yes String Delimiters, characters that separates


the tokens in the items String

varStatus no no String The name of the exported variable for


the status of the operation. The object
exported is of type
javax.servlet.jsp.jstl.core.Loop
TagStatus

begin yes no int beginning index (zero-based) of the


iteration. If not specified, iteration will
begin with the first token.

end yes no int end index of the iteration

step yes no int The loop will only process every "step"
tokens of the iteration, starting with
the first token

Example:

Mobile Application Development 19


J.E.D.I.

<select name="gender">
<c:forEach var="gender" items="Male,Female" delims=",">
<option value="<c:out value="${gender}"/>">
<c:out value="${gender}"/>
</option>
</c:forEach>
</table>

.4 JDBC

In this section, we will be discussing how to persist data or objects. For this functionality,
we will need a (relational) database. The JDBC API lets you perform queries and updates
on a database. Before we can use JDBC, we need to make sure that three prerequisites
are met:

• JDBC library - included in the JDK


• The Database Server - we will use MySQL (mysql.com)
• JDBC Driver - comes with your DBMS, install the jar mysql-connector-java-3.x.x-
bin.jar for JDBC 3.0

The table used in these examples can be recreated using this SQL CREATE AND INSERT
statements:

CREATE TABLE `task` (


`id` bigint(20) unsigned NOT NULL auto_increment,
`task` varchar(128) NOT NULL default '',
`duration` int(11) NOT NULL default '0',
`assignedTo` varchar(64) NOT NULL default '',
`status` char(1) NOT NULL default '',
PRIMARY KEY (`id`)
);

Mobile Application Development 20


J.E.D.I.

INSERT INTO `task`


(`id`, `task`, `duration`, `assignedTo`, `status`)
VALUES
(1,'connect to database',2,'alex','0'),
(2,'list table rows',4,'alex','0'),
(3,'update row',8,'you','0');

.4.1 Loading the Driver

To use the JDBC driver for a particular database, we have to load it using
Class.forName(). The driver name is dependent on the database driver that we will be
loading. In our case, we are loading the mysql jdbc driver:

String driver = "com.mysql.jdbc.Driver";


Class.forName(driver);

.4.2 Establishing a Connection

To establish a connection to the database, we will need the URL to the database. We will
also need access to that database. A working username and password are required to
establish a connection.

String url = "jdbc:mysql://localhost:3306/jedi";


String username = "root";
String password = "password";
conn = DriverManager.getConnection(url, username, password);

.4.3 Executing SQL queries

executeQuery returns a ResultSet object. To iterate on all the rows returned by the
query, we use the next() method. There are several methods that return the columns of
the current row, each for a specific datatype. In this example, we retrieved String and
integer variables using getString() and getInt():

statement = conn.createStatement();
String query = "SELECT task,duration,duration FROM task";
ResultSet rs = statement.executeQuery(query);
out.println("<table>");
out.println("<tr>");

Mobile Application Development 21


J.E.D.I.

out.println("<th>Task</th>");
out.println("<th>Duration</th>");
out.println("<th>Assigned to</th>");
out.println("</tr>");

while (rs.next()) {
String task = rs.getString("task");
int duration = rs.getInt("duration");
String assignedTo = rs.getString("assignedTo");

out.println("<tr>");
out.println("<td>" + task + "</td>");
out.println("<td>" + duration + "</td>");
out.println("<td>" + duration + "</td>");
out.println("</tr>");

}
out.println("</table>");

.4.4 Updating tables

To update tables (UPDATE, INSERT, DELETE), the Statement.executeUpdate() is used.

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


String duration = (String) request.getParameter("duration");
String assignedTo = (String) request.getParameter("assignedTo");
String status = (String) request.getParameter("status");
Long id = new Long(idStr);
String updateQuery;

ResultSet rs = dao.query("SELECT id from task WHERE id ='" + id + "'");


if (rs.next()){

Mobile Application Development 22


J.E.D.I.

// update task entry


updateQuery = "UPDATE task SET"
+ " task='" + (task != null? task:"") + "'"
+ ",duration='" + (duration != null ? duration:"") + "'"
+ ",assignedTo='" + (assignedTo != null ? assignedTo:"") + "'"
+ ",status='" + (status != null ? status:"") + "'"
+ " WHERE id=" + id;
} else {
// new task entry
updateQuery = "INSERT INTO task (task, duration, assignedTo, status) "
+ "VALUES ("
+ "'"+task+"',"
+ "'"+duration+"',"
+ "'"+assignedTo+"',"
+ "'"+status+"'"
+ ")";
}

statement.executeUpdate(updateQuery);

.5 XML

XML, the eXtensible Markup Language, is a text-based markup language. With XML, you
can present data in a structured text document.

Just like HTML, XML tags are defined using the angled brackets: <>. Unlike HTML
though, XML is easier to parse. An XML document is structured, with entities forming a
tree structure.

You can use any appropriate tag name that you like, as long as all the applications using
the XML document will use the same tag names. Tags can contain attributes. In the
example below, the first "task" has an "id" attribute of "1" while the second "task" has
an "id" attribute of "2".

<tasks>
<task id="1">
<name>connect to database</name>
<duration>2</duration>
<assignedTo>alex</assignedTo>
<status>0</status>

Mobile Application Development 23


J.E.D.I.

</task>
<task id="2">
<name>list table rows</name>
<duration>4</duration>
<assignedTo>alex</assignedTo>
<status>4</status>
</task>
</tasks>

.5.1 Parsing XML

As of the time of this document's writing, there have been no standard libraries defined
by a JCP process for parsing XML in CLDC. However, there are several XML libraries that
work with CLDC. One of them is NanoXML (http://nanoxml.sourceforge.net/). The
original version of NanoXML does not work with CLDC. You must download the source
code of the modified version that works with CLDC at
http://www.ericgiguere.com/nanoxml and include it in your mobile project under the
package name "nanoxml".

import java.io.*;
import java.util.*;
import nanoxml.*;

...

public String[] parseXml(String xml){


kXMLElement root = new kXMLElement();
try {
root.parseString(xml);

Vector taskList = root.getChildren();


Vector items = new Vector();

for (int i=0; i<taskList.size(); i++){


kXMLElement task = (kXMLElement) taskList.elementAt(i);
String tagName = task.getTagName();

if (tagName != null && tagName.equalsIgnoreCase("task")){


Vector taskProperties = task.getChildren();
String[] fieldNames = {

Mobile Application Development 24


J.E.D.I.

"name", "duration", "assignedTo", "status"


};
String[] fields = new String[fieldNames.length];
String id = task.getProperty("id", "0");

for (int j=0; j<taskProperties.size(); j++){


kXMLElement prop =
(kXMLElement) taskProperties.elementAt(j);
String propTagName = prop.getTagName();

if (propTagName != null){
for (int p=0; p<fieldNames.length; p++){
if (propTagName.equalsIgnoreCase(
fieldNames[p])){

fields[p] = prop.getContents();
}
}
}
}

items.addElement(id + ": " + fields[0]);


}
}

String[] itemArr = new String[items.size()];


items.copyInto(itemArr);
return itemArr;
} catch( kXMLParseException ke ){
return(null);
}
}

.6 Exercises

.6.1 Headers in a table w/ alternating row color

Write a JSTL code that will iterate over the implicit Map "header" and display the header
key/name and value in an HTML table. Odd numbered rows should have the background
color of lightyellow (<tr bgcolor="lightyellow">...). Note that the varStatus index start

Mobile Application Development 25


J.E.D.I.

with zero. Note that the (header) Map has the property "key" and "value".

Sample Output:

accept-
gzip,deflate
encoding

connection keep-alive

accept-
en-us,en;q=0.5
language

host localhost:8084

accept-charset ISO-8859-1,utf-8;q=0.7,*;q=0.7

Mozilla/5.0 (Linux; U; Linux v0.99; en-US) Gecko/20050511


user-agent
Firefox/1.2.3

text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/pl
accept
ain;q=0.8,image/png,*/*;q=0.5

keep-alive 300

.6.2 Servlets and JSP

Create a servlet and JSTL application that will display in XML format an array of objects.
The object properties are: name and ip address. The Java class should look like this:

public class Host {


private String name;
private String ip;

public Host(String name, String ip) {


this.name = name;
this.ip = ip;
}

public String getName(){ return(name); }


public String getIp(){ return(ip); }
public void setName(String name){ this.name = name; }
public void setIp(String ip){ this.ip = ip; }
}

You should pass a static array of Hosts from the Servlet into the JSP using

Mobile Application Development 26


J.E.D.I.

request.setAttribute().

Host[] hosts = {
new Host("localhost", "127.0.0.1"),
new Host("java.sun.com", "1.2.3.4")
};

The XML output should look like this:

<hosts>
<host name="localhost">
<ip>127.0.0.1</ip>
</host >
<host name="java.sun.com">
<ip>1.2.3.4</ip>
</host >
</hosts>

Mobile Application Development 27