TABLE OF CONTENTS (HIDE)

Java Server-side Programming

Getting started with JSP by Examples

Introduction

JavaServer Page (JSP) is Java's answer to the popular Microsoft's Active Server Pages (ASP) and PHP. JSP, like ASP and PHP, provides a simplified and fast mean to generate dynamic web contents. It allows you to mix static HTML with dynamically generated HTML - in the way that the business logic and the presentation are well separated.

The advantages of JSP are:

  1. Separation of static and dynamic contents: JSP enables the separation of static contents from dynamic contents.  The dynamic contents are generated via programming logic and inserted into the static template. This greatly simplifies the creation and maintenance of web contents.
  2. Reuse of components and tag libraries: The dynamic contents can be provided by reusable components such as JavaBean, Enterprise JavaBean (EJB) and tag libraries - you do not have to re-inventing the wheels.
  3. Java's power and portability
JSPs are Internally Compiled into Java Servlets

That is to say, anything that can be done using JSPs can also be accomplished using Java servlets. However, it is important to note that servlets and JSPs are complementary technologies, NOT replacement of each other. Servlet can be viewed as "HTML inside Java", which is better for implementing business logic - as it is Java dominant. JSP, on the other hand, is "Java inside HTML", which is superior for creating presentation - as it is HTML dominant. In a typical Model-View-Control (MVC) application, servlets are often used for the Controller (C), which involves complex programming logic. JSPs are often used for the View (V), which mainly deals with presentation. The Model (M) is usually implemented using JavaBean or EJB.

Apache Tomcat Server

JSPs, like servlets, are server-side programs run inside a HTTP server. To support JSP/servlet, a Java-capable HTTP server is required. Tomcat Server (@ https://tomcat.apache.org) is the official reference implementation (RI) for Java servlet and JSP, provided free by Apache (@ https://www.apache.org) - an open-source software foundation.

First JSP Example - "Java inside HTML"

Let's begin with a simple JSP example. We shall use the webapp called "hello" that we have created in our earlier servlet exercise. Use a programming text editor to enter the following HTML/JSP codes and save as "first.jsp" (the file type of ".jsp" is mandatory) in your webapp's home directory (i.e., "webapps\hello").

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html>
<head><title>First JSP</title></head>
<body>
  <%
    double num = Math.random();
    if (num > 0.95) {
  %>
      <h2>You'll have a luck day!</h2><p>(<%= num %>)</p>
  <%
    } else {
  %>
      <h2>Well, life goes on ... </h2><p>(<%= num %>)</p>
  <%
    }
  %>
  <a href="<%= request.getRequestURI() %>"><h3>Try Again</h3></a>
</body>
</html>

To execute the JSP script: Simply start your Tomcat server and use a browser to issue an URL to browse the JSP page (i.e., http://localhost:8080/hello/first.jsp).

From your browser, choose the "View Source" option to check the response message. It should be either one of the followings depending on the random number generated.

<!DOCTYPE html>
<html>
<h2>You'll have a luck day!</h2>
<p>(0.987)</p>
<a href="first.jsp"><h3>Try Again</h3></a>
</html>
<!DOCTYPE html>
<html>
<h2> Well, life goes on ... </h2>
<p>(0.501)</p>
<a href="first.jsp"><h3>Try Again</h3></a>
</html>

It is important to note that the client is not able to "view" the original JSP script (otherwise, you will have security exposure as the Java codes might contain your MySQL password), but merely the result generated by the script.

Explanations

  1. A JSP script is a regular HTML page containing Java programs. Recall that JSP is "Java inside HTML" (whereas servlet is "HTML inside Java"). The Java statements are enclosed by <% ... %> (called JSP scriptlet) or <%= ... %> (called JSP expression).
  2. JSP Scriptlet <% ... %> is used to include Java statements.
  3. JSP Expression <%= ... %> is used to evaluate a single Java expression and display its result.
  4. The method request.getRequestURI() is used to retrieve the URL of the current page. This is used in the anchor tag <a> for refreshing the page to obtain another random number.
Behind the Scene

When a JSP is first accessed, Tomcat converts the JSP into a servlet; compile the servlet, and execute the servlet. Check out the generated servlet for "first.jsp", and study the JSP-to-servlet conversion. Look under Tomcat's "work\Catalina\localhost\hello\org\apache\jsp" for "first_jsp.java".

The relevant part of the generated servlet is extracted as follows (with some simplifications):

......
out.write("<!DOCTYPE html>\r\n");
out.write("<html>\r\n  ");
double num = Math.random();
if (num > 0.95) {
   out.write("<h2>You will have a luck day!");
   out.write("</h2><p>(");
   out.print( num );
   out.write(")</p>\r\n");
} else {
   out.write("\r\n    ");
   out.write("<h2>Well, life goes on ... ");
   out.write("</h2><p>(");
   out.print( num );
   out.write(")</p>\r\n  ");
}
out.write("<a href=\"");
out.print( request.getRequestURI() );
out.write("\">");
out.write("<h3>Try Again</h3></a>\r\n");
out.write("</html>\r\n");
......
Explanation
  1. The HTML statements are written out as part of the response via out.write(), as "it is".
  2. The JSP scriptlets <% ... %> are kept, as "it is", in the converted servlet as the program logic.
  3. The JSP expressions <%= ... %> are placed inside a out.print(). Hence, the expression will be evaluated, and the result of the evaluation written out as part of the response message.

Compare the JSP script and the internally generated servlet, you shall understand that servlet is "HTML inside Java", whereas JSP is "Java inside HTML".

Subsequent accesses to the same JSP will be much faster, because they will be re-directed to the converted and compiled servlet directly (no JSP-to-servlet conversion and servlet compilation is needed again), unless the JSP has been modified.

Revisit Java Servlets

A typical Java servlet (as shown below) contains three kinds of methods: init(), destroy(), and one or more service() methods such as doGet() and doPost(). init() runs when the servlet is loaded. destroy() runs when the servlet is unloaded. service() runs once per HTTP request. The service() methods takes two arguments: request and response, corresponding to the HTTP request and response messages respectively. A PrintWriter called out is created for writing out the response to the network.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import java.io.*;
import jakarta.servlet.*;      // Tomcat 10
import jakarta.servlet.http.*;
 
public class ...Servlet extends HttpServlet {
 
   // Runs when the servlet is loaded onto the server.
   public void init() {
      ......
   }
 
   // Runs on a thread whenever there is HTTP GET request
   // Take 2 arguments, corresponding to HTTP request and response
   public void doGet(HttpServletRequest request, HttpServletResponse response)
         throws IOException, ServletException {
 
      // Set the MIME type for the response message
      response.setContentType("text/html");
      // Write to network
      PrintWriter out = response.getWriter();
 
      // Your servlet's logic here
      out.println("<!DOCTYPE html>");
      out.println("<html>");
      out.println( ...... );
      out.println("</html>");
   }
 
   // Runs as a thread whenever there is HTTP POST request
   public void doPost(HttpServletRequest request, HttpServletResponse response)
         throws IOException, ServletException {
      // do the same thing as HTTP GET request
      doGet(request, response);
   }
 
   // Runs when the servlet is unloaded from the server.
   public void destroy() {
      ......
   }
 
   // Other instance variables and methods
 }

Java servlet produces HTML codes by calling out.print() methods. You have to hardcode all the HTML tags (and cannot use any WYSIWYG web authoring tools). Any change to the web page's presentation (such as background color and font size) requires re-coding and re-compilation of servlet program. Servlet, in a nutshell, is "HTML inside Java", whereas JSP is "Java inside HTML".

Second JSP example - Echoing HTML Request Parameters

Enter the following JSP script and save as "echo.jsp" in your webapp's root directory.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<!DOCTYPE html>
<html>
<head>
  <title>Echoing HTML Form Query Parameters</title>
</head>
<body>
  <h3>Choose an author:</h3>
  <form method="get">
    <input type="checkbox" name="author" value="Tan Ah Teck">Tan
    <input type="checkbox" name="author" value="Mohd Ali">Ali
    <input type="checkbox" name="author" value="Kumar">Kumar
    <input type="submit" value="Query">
  </form>
 
  <%
  String[] authors = request.getParameterValues("author");
  if (authors != null) {
  %>
    <h3>You have selected author(s):</h3>
    <ul>
  <%
      for (int i = 0; i < authors.length; ++i) {
  %>
        <li><%= authors[i] %></li>
  <%
      }
  %>
    </ul>
    <a href="<%= request.getRequestURI() %>">BACK</a>
  <%
  }
  %>
</body>
</html>

Browse the JSP page created and study the generated servlet.

Explanations

  1. This HTML page has a form with 3 checkboxes. The "name=value" pair of the checkboxes is "author=so_and_so". No "action" attribute is specified, the default "action" is the current page (i.e. the query will be sent to the same page).
  2. The JSP scriptlet checks if the query parameter "author" exists to decide whether to dynamically generate the enclosed codes. "author" parameter is absent when the page is first requested. Once the client fills in the form (by checking the boxes) and submits the form, "author" will be present in the HTTP request, and submitted to the same page for processing (with the default <form>’s "action" attribute).
  3. The request.getParameterValues() is used to retrieve all the values of the query parameter. The values are echoed back using an unordered list.

JSP Scripting Elements

JSP provides the following scripting elements:

  • JSP Comment <%-- comments -->
  • JSP Expression <%= Java Expression %>
  • JSP Scriptlet <% Java Statement(s) %>
  • JSP Directive <%@ page|include ... %>

To simplify the access of the HTTP request and response messages, JSP has pre-defined the following variables:

  • request: corresponds to the HTTP request message.
  • response: corresponds to the HTTP response message.
  • out: corresponds to the HTTP response message’s output stream.
  • others such as session, page, application, pageContext, which are outside the scope of this tutorial.

JSP comment <%-- comments --%>

JSP comments <%-- comments --%> are ignored by the JSP engine. For example,

<%-- anything but a closing tag here will be ignored -->

Note that HTML comment is <!-- comments -->. JSP expression within the HTML comment will be evaluated. For example,

<!-- HTML comments here <%=  Math.random() %> more comments -->

JSP Expression <%= Java Expression %>

JSP Expression can be used to insert a single Java expression directly into the response message. This expression will be placed inside a out.print() method. Hence, the expression will be evaluated and printed out as part of the response message.  Any valid Java expression can be used.  There is no semi-colon at the end of the expression. For examples:

<p>The square root of 5 is <%= Math.sqrt(5) %></p>
<h5><%= item[10] %></h5>
<p>Current time is: <%=  new java.util.Date() %></p>

The above JSP expressions will be converted to:

out.write("<p>The square root of 5 is ");
out.print( Math.sqrt(5) );
out.write("</p>");
out.write("<h5>");
out.print( item[10] );
out.write("</h5>");
out.write("<p>Current  time is: ");
out.print( new java.util.Date()  );
out.write("</p>");

You can use the pre-defined variables, such as request, in the expressions. For examples:

<p>You have choose author <%= request.getParameter("author") %></p>
<%= request.getRequestURI() %>
<%= request.getHeader("Host") %>

JSP Scriptlet <% Java statement(s) %>

JSP scriptlets allow you to do more complex operations than inserting a single Java expression (with the JSP expression). JSP scriptlets let you insert an arbitrary sequence of valid Java statement(s) into the service() method of the converted servlet. All the Java statements in a scriptlet are to be terminated with a semi-colon. For example:

<%
  String author = request.getParameter("author");
  if (author != null && !author.equals(""))) { 
%>
    <p>You have choose author <%= author %></p>
<%
  }
%>

In the converted servlet, the above will be inserted into the service() method as follows:

String author = request.getParameter("author");
if (author != null && !author.equals(""))) {
  out.write("<p>You have choose author ");
  out.print( author );
  out.write("</p>");
}

Notice that the Java codes inside a scriptlet are inserted exactly as they are written, and used as the programming logic. The HTML codes are passed to an out.write() method and written out as part of the response message.

JSP Directive <%@ page|include ... %>

JSP directives provide instructions to the JSP engine. The syntax of the JSP directive is:

<%@ directive_name
  attribute1="value1"
  attribute2="value2"
  ......
  attributeN="valueN" %>
JSP page Directive

The "page" directive lets you import classes and customize the page properties. For examples,

<%-- import package java.sql.*  -->
<%@ page import="java.sql.*" %>
 
<%-- Set the output MIME type  -->
<%@ page contentType="image/gif" %>
 
<%-- Set an information message for getServletInfo() method -->
<%@ page info="Hello-world example" %>
JSP include Directive

The "include" directive lets you include another file(s) at the time when the JSP page is compiled into a servlet. You can include any JSP files, or static HTML files. You can use include directive to include navigation bar, copyright statement, logo, etc. on every JSP pages. The syntax is:

<%@ include file="url" %>

For example:

<%@ include file="header.html" %>
......
<%@ include file="footer.html" %>

JSP Database Example

Let's revisit our e-shop, which was created using Java Servlet.

Database
Database: ebookshop
Table: books
+-------+----------------------------+---------------+---------+-------+
| id    | title                      | author        | price   | qty   |
| (INT) | (VARCHAR(50))              | (VARCHAR(50)) | (FLOAT) | (INT) |
+-------+----------------------------+---------------+---------+-------+
| 1001  | Java for dummies           | Tan Ah Teck   | 11.11   | 11    |
| 1002  | More Java for dummies      | Tan Ah Teck   | 22.22   | 22    |
| 1003  | More Java for more dummies | Mohammad Ali  | 33.33   | 33    |
| 1004  | A Cup of Java              | Kumar         | 44.44   | 44    |
| 1005  | A Teaspoon of Java         | Kevin Jones   | 55.55   | 55    |
+-------+----------------------------+---------------+---------+-------+
Querying - "query.jsp"

Let's create the query page called "query.jsp".

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<!DOCTYPE html>
<html>
<head>
  <title>Book Query</title>
</head>
<body>
  <h1>Another E-Bookstore</h1>
  <h3>Choose Author(s):</h3>
  <form method="get">
    <input type="checkbox" name="author" value="Tan Ah Teck">Tan
    <input type="checkbox" name="author" value="Mohd Ali">Ali
    <input type="checkbox" name="author" value="Kumar">Kumar
    <input type="submit" value="Query">
  </form>
 
  <%
    String[] authors = request.getParameterValues("author");
    if (authors != null) {
  %>
  <%@ page import = "java.sql.*" %>
  <%
      Connection conn = DriverManager.getConnection(
          "jdbc:mysql://localhost:3306/ebookshop", "myuser", "xxxx"); // <== Check!
      // Connection conn =
      //    DriverManager.getConnection("jdbc:odbc:eshopODBC");  // Microsoft Access
      Statement stmt = conn.createStatement();
 
      String sqlStr = "SELECT * FROM books WHERE author IN (";
      sqlStr += "'" + authors[0] + "'";  // First author
      for (int i = 1; i < authors.length; ++i) {
         sqlStr += ", '" + authors[i] + "'";  // Subsequent authors need a leading commas
      }
      sqlStr += ") AND qty > 0 ORDER BY author ASC, title ASC";
 
      // for debugging
      System.out.println("Query statement is " + sqlStr);
      ResultSet rset = stmt.executeQuery(sqlStr);
  %>
      <hr>
      <form method="get" action="order.jsp">
        <table border=1 cellpadding=5>
          <tr>
            <th>Order</th>
            <th>Author</th>
            <th>Title</th>
            <th>Price</th>
            <th>Qty</th>
          </tr>
  <%
      while (rset.next()) {
        int id = rset.getInt("id");
  %>
          <tr>
            <td><input type="checkbox" name="id" value="<%= id %>"></td>
            <td><%= rset.getString("author") %></td>
            <td><%= rset.getString("title") %></td>
            <td>$<%= rset.getInt("price") %></td>
            <td><%= rset.getInt("qty") %></td>
          </tr>
  <%
      }
  %>
        </table>
        <br>
        <input type="submit" value="Order">
        <input type="reset" value="Clear">
      </form>
      <a href="<%= request.getRequestURI() %>"><h3>Back</h3></a>
  <%
      rset.close();
      stmt.close();
      conn.close();
    }
  %>
</body>
</html>
Explanations
  1. This HTML page has a form with 3 checkboxes. The "name=value" pair of the checkboxes is "author=so_and_so". No "action" attribute is specified, hence, it defaulted to current page. The processing script is contained in the same page.
  2. The method request.getParameter("author") is used to check if the query parameter "author" exists.  "author" is absent during the first reference of the page.
  3. The <%@ page .. %> contains a JSP "page" directive to import the java.sql package.
  4. The scriptlet performs the database query operation. The steps are:
    1. Establish a database connection via a java.sql.Connection object;
    2. Allocate a java.sql.Statement object under the Connection;
    3. Prepare a SQL SELECT string;
    4. Execute the SQL SELECT using executeQuery() method. The result of query is returned in an object of java.sql.ResultSet;
    5. Process the ResultSet row by row via ResultSet.next();
    6. Free resources and close the Connection.
  5. The query result is tabulated in a HTML table. Note the mixing of HTML and Java in producing the table.

Notice that JSP carries out the presentation much better and neater than servlet. The presentation can be changed easily with JSP. The JSP pages can be created and modified using a WYSIWYG web authoring tool and reload to see the effect on the presentation.  Whereas, in the case of servlet, you have to explicitly code all the HTML tags inside the servlet program and re-compile the program.

Ordering - "order.jsp"

Let's write the "order.jsp" for processing the order, by updating the appropriate records in the database.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<html>
<head>
  <title>Order Book</title>
</head>
 
<body>
  <h1>Another E-Bookstore</h1>
  <h2>Thank you for ordering...</h2>
 
  <%
    String[] ids = request.getParameterValues("id");
    if (ids != null) {
  %>
  <%@ page import = "java.sql.*" %>
  <%
      Connection conn = DriverManager.getConnection(
          "jdbc:mysql://localhost:3306/ebookshop", "myuser", "xxxx"); // <== Check!
      // Connection conn =
      //    DriverManager.getConnection("jdbc:odbc:eshopODBC");  // Access
      Statement stmt = conn.createStatement();
      String sqlStr;
      int recordUpdated;
      ResultSet rset;
  %>
      <table border=1 cellpadding=3 cellspacing=0>
        <tr>
          <th>Author</th>
          <th>Title</th>
          <th>Price</th>
          <th>Qty In Stock</th>
        </tr>
  <%
      for (int i = 0; i < ids.length; ++i) {
        // Subtract the QtyAvailable by one
        sqlStr = "UPDATE books SET qty = qty - 1 WHERE id = " + ids[i];
        recordUpdated = stmt.executeUpdate(sqlStr);
        // carry out a query to confirm
        sqlStr = "SELECT * FROM books WHERE id =" + ids[i];
        rset = stmt.executeQuery(sqlStr);
        while (rset.next()) {
  %>
          <tr>
            <td><%= rset.getString("author") %></td>
            <td><%= rset.getString("title") %></td>
            <td>$<%= rset.getInt("price") %></td>
            <td><%= rset.getInt("qty") %></td>
          </tr>
  <%    }
        rset.close();
      }
      stmt.close();
      conn.close();
    }
  %>
  </table>
  <a href="query.jsp"><h3>BACK</h3></a>
</body>
</html>

JSP Exercises

[TODO]

REFERENCES & RESOURCES

  1. JavaServer Pages Technology @ http://java.sun.com/products/jsp.
  2. Java Servlet Technology @ http://java.sun.com/products/servlet.
  3. Apache Tomcat @ http://tomcat.apache.org, Apache Software Foundation.
  4. The Java EE 5 Tutorial @ http://java.sun.com/javaee/5/docs/tutorial/doc/.
  5. Marty Hall, et al., "Core Servlets and JavaServer Pages", vol.1 (2nd eds, 2003) and vol. 2 (2nd eds, 2006), Prentice Hall.
  6. Java Database Connectivity (JDBC) @ http://java.sun.com/products/jdbc.
  7. RFC2616 "Hypertext Transfer Protocol HTTP 1.1", World-Wide-Web Consortium (W3C), June 1999.
  8. "HTML 4.01 Specification", W3C Recommendation, 24 Dec 1999.