CSCI.4220 Network Programming
Fall, 2006
Class 17:Tomcat, Servlets, Java Server Pages (JSPs)

Java Servlets

This completes our discussion of client side programming. What is on the server side?

Dynamic Content - started with cgi

Then came servlets - why are servlets better than cgi?

But you still have to generate the entire HTML from within your program

Other similar technologies include Microsoft ASP, BEA weblogic, Cold Fusion, IBM WebSphere, Sun's Java Web Server, Allaire's JRun,

More recently, server scripting languages like PHP and Ruby have become popular, and Perl has been used as a cgi server scripting language for years.

Tomcat

Apache Jakarta Tomcat is a servlet container. You should download it from http://tomcat.apache.org and install it on your laptop.

You need jdk1.4 or higher (latest is 1.5) installed.

To test your installation, point your browser to http://localhost:8080 and you should see the tomcat home page.

CATALINA_HOME refers to the jakarta directory

The tomcat directory has a number of subdirectories.

Servlets

Servlets are java programs running inside a web server. They are accessed thru a URL and typically return HTML.

Here is a the structure of a basic servlet to handle get requests

/* servlet skeleton    compile with 
   -classpath CATALINA_HOME\common\lib\servlet-api.jar */
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class SomeServlet extends HttpServlet {
  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
      throws ServletException, IOException {

       response.setContentType("text/html");

       String s = request.getParamater(pName);    
    
       PrintWriter out = response.getWriter();
       // Use ``out'' to send content to browser
  }
}
Here is the on-line help page for the HttpServlet class

An httpServeletRequest has a method getParameter which can be used to get the value of a parameter sent by the client. Here is the on-line help for an HttpServletRequest

Here is a full java program to convert dollars to Euros CurrencyConverter.java

/* CurrencyConverter.java: A servlet to convert dollars to Euros */
/* compile with -classpath <CATALINA_HOME>\common\lib\servlet-api.jar */
import java.io.*;
import java.util.*;
import java.text.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class CurrencyConverter extends HttpServlet {
    private static final double EXCHANGE_RATE = 0.79;
    public void doGet(HttpServletRequest req,
                      HttpServletResponse res)
              throws ServletException, IOException {
           res.setContentType("text/html");
           PrintWriter out = res.getWriter();
           out.println("<html>");
           out.println("<head><title>Currency Conversion</title></head>");
           out.println("<body>");
           String amount = req.getParameter("amount");
           try {
               NumberFormat nf = NumberFormat.getInstance();
               double Value = nf.parse(amount).doubleValue();
               Value *= EXCHANGE_RATE;
               nf.setMaximumFractionDigits(2);
               nf.setMinimumFractionDigits(2);
               out.println("<big>" + "$" +
                    amount + " = &euro;" +
                    nf.format(Value) + "</BIG>");
            }
            catch (ParseException e) {
                out.println("Bad number format");
            }
            out.println("</body></html>");
       }
}
Here is the html front end for it, CurrencyConverter.html.
<html>
  <head>
     <title>Currency Converter</title>
  </head>
  <body>
     <form method=GET action="servlet/CurrencyConverter">
         <h3>Simple Currency Converter</h3>
         <p>Use this form to convert US dollars to Euros (€)
         </p>
       
         Type the amount to be converted in the box
         <input type=text name="amount">
         <input type=submit>
    </form>
  </body>
</html>
To deploy this
  1. put the html file in the directory CATALINA_HOME\webapps\servlets-examples
  2. compile the java file, and put the class in the directory CATALINA_HOME\webapps\servlets-examples\WEB-INF\classes
  3. Edit the deployment file CATALINA_HOME\webapps\servlets-examples\WEB-INF\web.xml by adding the following entries (it should be obvious where they go in the file)
    <web-app>
       ....
       <servlet>
           <servlet-name>CurrencyConverter</servlet-name>
           <servlet-class>CurrencyConverter</servlet-class>
       </servlet>
       ...
       <servlet-mapping>
           <servlet-name>CurrencyConverter</servlet-name>
           <url-pattern>/servlet/CurrencyConverter</url-pattern>
       </servlet-mapping>
       ...
    
  4. Restart tomcat
  5. In your favorite browser, go to
    http://localhost:8080/servlets-examples/CurrencyConverter.html

The life of a servlet
An instance is created, often at startup time, by the container, This calls the init() function. While it is running each request calls the service() method, which in turn implements doGet() or doPost(). Each request runs in a separate thread. Eventually it is destroyed with the destroy() method.

The get request is supposed to be idempotent (calling it more than once is like calling it once). The post request is not necessarily idempotent (hitting the submit button twice). But there is nothing in the code to ensure this.

Besides parameters, what else can you get from the request object

string client = request.getHeader("User-Agent");
Cookie[] cookies = request.getCookies();
HttpSession session = request.getSession();
String theMethod = request.getMethod();
InputStream in = request.getInputStream();
What other response methods would you use besides getWriter()

The servlet can redirect response.sendRedirect("http.//..."); This sends a 301 error code to the browser along with the url, and the browser should know enough to contact the new url

Features of a web app

One web app can have multiple servlets

ServletConfig is one per servlet
ServletContext is one per web app

The general form to access a servlet is

http://<host>:port/<Context Root>/<Servlet Path>?query-string

The Deployment Descriptor

CATALINA_HOME/webapps/contextroot/WEB-INF/web.xml

Why the second name? 1 - it makes it easier to move things around and it hides the file structure from outsiders. Using the deployment descriptor to map urls to servlets <servlet> maps internal names to fully qualified class names
<servlet-mapping> maps internal names to public URL names

You can initialize parameters in the Deployment Descriptor file

<servlet>
  ...
<init-param>
<param-name>RATE<param-name>
<param-value>.82</param-value>
</init-param>
</servlet>
in the servlet code String s = getServletContext().getInitParameter("RATE");

Distinguish between servlet init parameters and context init parameters

You can also change the url

    <servlet>
        <servlet-name>CurrencyConverter</servlet-name>
        <servlet-class>CurrencyConverter</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>CurrencyConverter</servlet-name>
        <url-pattern>/dollar2euro</url-pattern>
    </servlet-mapping>
But you have to change the action in the html code action=dollar2euros

You do this for two reasons, it makes it easier to move stuff around. you just have to change the dd, not the html file, and it is a security measure, it hides the file structure from the user.

Sessions

By default, a servlet is stateless, but often multiple connections apply to the same session. One way to maintain session information is with an HttpSession object

On the client's first request, the container generates a unique session id and sends it back to the client. All subsequent requests from the client will contain this.

This is done with cookies, but the Httpsession hides the cookie details from the application.

HttpSession session = request.getSession();
if (session.isNew()) // this is a new session
session.setAttribute("foo","bar");
session.getAttribute("foo");
This only works if the client accepts cookies

On to JSPs (Java Server Pages)

A JSP file is an html file with embedded jsp tags. There are many different kinds of jsp tags.

Here is a very simple jsp file

<html>
  <head>
    <title>Date JSP</title>
  </head>

  <body>
    <h1>Date JSP</h1>
    <p>The Current Time is:
          <%= new java.util.Date() %>
    </p>
  </body>
</html>
This file has a .jsp suffix. The first time it is invoked, Jasper reads this file, generates a java servlet file, compiles it, and puts the class file in the appropriate directory.

JSP syntax

There are three types of elements, Directives, Scripting elements, and Action elements

A directive has this syntax
<%@ directive (attribute=''value'')* %>

There are three types of directives: page directives, include directives , tag library directives

The page directive has eleven possible attributes, of which we care about only one, import
<%@ page import="java.io.*" %>

The include directive allows you to include the contents of other files in your jsp page
<%@ include file=''includes/headers.html'' %>

We will not discuss tag libraries in this course, but it is possible to define your own jsp tags and put them in a tag library.

Scripting elements There are three types of scripting elements: scriptlets, declarations, and expressions

scriptlets are code blocks of java, they start with <% and end with %> The code is copied directly into the java file created by jasper. Here is a short program which uses the page directive and scriptlets.

<%@ page import="java.io.*" %>
<%@ page import="java.util.*" %>
<%@ page import="java.text.*" %>
<%! private static final double EXCHANGE_RATE = 0.79; %>

<%
    String amount = request.getParameter("amount");
           try {
               NumberFormat nf = NumberFormat.getInstance();
               double Value = nf.parse(amount).doubleValue();
               Value *= EXCHANGE_RATE;
               nf.setMaximumFractionDigits(2);
               nf.setMinimumFractionDigits(2);
            
%>

<html>
    <head><title>Currency Conversion JSP</title></head>
    <body>
        <big>
            $ <%= amount %> =
            &euro; <%= nf.format(Value) %>
        </big>
    </body>
</html>
<% 
 }
 catch (ParseException e) {
    out.println("Bad number format");
}
%>
You can look at the java file which is created by jasper. This is often useful for debugging. Here is the file created from the above jsp. It's path name is CATALINA_HOME\work\Catalina\localhost\myJSPApp\org\apache\jsp\CurrencyConverter_jsp.java
   package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.io.*;
import java.util.*;
import java.text.*;

public final class CurrencyConverter_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {

 private static final double EXCHANGE_RATE = 0.79; 
  private static java.util.Vector _jspx_dependants;

  public java.util.List getDependants() {
    return _jspx_dependants;
  }

  public void _jspService(HttpServletRequest request, HttpServletResponse response)
        throws java.io.IOException, ServletException {

    JspFactory _jspxFactory = null;
    PageContext pageContext = null;
    HttpSession session = null;
    ServletContext application = null;
    ServletConfig config = null;
    JspWriter out = null;
    Object page = this;
    JspWriter _jspx_out = null;
    PageContext _jspx_page_context = null;


    try {
      _jspxFactory = JspFactory.getDefaultFactory();
      response.setContentType("text/html");
      pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write('\n');
      out.write('\n');
      out.write('\n');
      out.write('\n');
      out.write('\n');

    String amount = request.getParameter("amount");
           try {
               NumberFormat nf = NumberFormat.getInstance();
               double Value = nf.parse(amount).doubleValue();
               Value *= EXCHANGE_RATE;
               nf.setMaximumFractionDigits(2);
               nf.setMinimumFractionDigits(2);
            

      out.write("\n");
      out.write("\n");
      out.write("<html>\n");
      out.write("    <head><title>Currency Conversion JSP</title></head>\n");
      out.write("    <body>\n");
      out.write("        <h1>Conversion from dollars to euros</h1>\n");
      out.write("        <p>\n");
      out.write("        <big>\n");
      out.write("            $ ");
      out.print( amount );
      out.write(" =\n");
      out.write("            € ");
      out.print( nf.format(Value) );
      out.write("\n");
      out.write("        </big>\n");
      out.write("    </body>\n");
      out.write("</html>\n");
 
 }
 catch (ParseException e) {
    out.println("Bad number format");
}

      out.write('\n');
      out.write('\n');
    } catch (Throwable t) {
      if (!(t instanceof SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          out.clearBuffer();
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
      }
    } finally {
      if (_jspxFactory != null) _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}
JSP Implicit Objects There are a number of implicit objects which will be in the java file created by your jsp, and you can access these from a scriptlet. Here they are. The types should be obvious
request
response
out
session
application
config
pageContext
page
exception
Declarations Declarations allow you to declare methods and variables that can be used from any point in a jsp page. They start with <%! and end with %>

Expressions get evaluated when the jsp page is requested and the result is converted to a string and fed to the print method of the out implicit object. The first jsp (date) used an expression.

Action elements

Here is a list of action elements

jsp.useBean
jsp.setProperty
jsp.getProperty
jsp.param
jsp.include
jsp.forward
jsp.plugin
jsp.params
jsp.fallback
We are only concerned with the first three, which pertain to javabeans. A javabean is a regular java class with some special characteristics The idea behind java beans is that you can separate the web design (the html) from the application logic (the bean). Servlets can do the same thing, but a web page which intermixes lots of servlets and html is confusing.

The jsp:useBean action is a directive to the jsp compiler to use a particular bean. Here is an example.

<jsp:useBean id="converter" class="converter.CurrencyConverterBean">

There is an optional scope variable which can have these values: page (default), request, session, application

The jsp.setProperty and jsp.getProperty are used to set and get variables in the bean.

<jsp:setProperty name="converter" property="amount" value="3"/>
<jsp:getProperty name="converter" property="Value"/>

Here is our currency converter program using a javabean. The first program is the bean itself, which is just a simple java class which has the bean characteristics.

package converters;

import java.util.*;
import java.text.*;

public class CurrencyConverterBean {
    private static final double EXCHANGE_RATE = 0.79;
    private NumberFormat nf = NumberFormat.getInstance();
    private String amount;

    public void setAmount(String amount) {
        this.amount = amount;
    }
    public String getEuroval() {
        try {
             double Value = nf.parse(amount).doubleValue();
             Value *= EXCHANGE_RATE;
             nf.setMaximumFractionDigits(2);
             nf.setMinimumFractionDigits(2);
             return "€" + nf.format(Value);
          }
          catch (ParseException e) {
             return ("Bad number format");
          }
     }
}
Here is the jsp file that uses this bean.
<jsp:useBean id="converter" class="converters.CurrencyConverterBean" scope="page" >
<jsp:setProperty name="converter" property="amount" />
</jsp:useBean>

<html>
    <head><title>Currency Converter JSP</title></head>
    <body>
       <big>
           <jsp:getProperty name="converter" property="amount" /> = <jsp:getProperty name="converter" property="euroval" />
</big>
</body>
</html>

If you don't like my example of JSP and Beans, here is an article called What are JavaBeans? Read both this and the next article Calling JavaBeans from a JSP page.

There are lots of jsp resources on the web. Here is a link to the sun page on jsp syntax.

Here's a very comprehensive tutorial on servlets and JSPs. The link to the JSP material is at the bottom of the righthand column.