OOP-ResearchMake It Simpler by Object Oriented Programming

ServletContext, JSP, Servlets, Apache Tomcat, EJB, JDBC

An object in the ServletContext can update its enclosing data by accessing SQL database through EJB or JDBC periodically. Our Servlets can get the latest data without the connection to the the SQL.

As you know, any Java object can be stored in the ServletContext and shared among the multiple Servlets which belong to the same context. From the Java object stored in the ServletContext, our Servlets can retrieve the data which is independent from the HTTP request.
The data in such an object can be updated by the external resources, not only by the request to our Servlets. For example, an object in the ServletContext can update its enclosing data by accessing SQL database through EJB or JDBC periodically. Our Servlets can get the latest data without the connection to the the SQL.

This article describes how to dispatch the independent Thread by the object stored in the ServeltContext. By OOP-Research


Independent from request, but not static

In the general design of web application, the Servlets or its derivative is responsible for the logic part, while JSP for GUI part. To achieve its task, our Servlets may lookup the SQL table and pass the result to the JSP. Or they may invoke some remote method on EJB to retrieve the data. Our Servlets can do anything you like. And as a result of any logic related task, our Servlets must provide the JSP with the appropriate data.
There are 2 kinds of "appropriate data":

  • Data corresponding to the request
  • Data independent from the request
As you know, Data corresponding to the request must be generated based on the request parameter values. For example, when the user post the HTTP request for the stock price of OOP-Research (although it is not listed in any stock market!), our Servlets may query the SQL table by the value in the request parameter.
But at the same time, our web application may disply the latest DowJonesAverage30 on all the resulting web pages, regardless the request from the user. In this situation, the latest DowJonesAverage30 is Data independent from the request. It does not differ with the HTTP requests dispatched by the users. The DowJonesAverage30 will always be shown, regardless whether the user queries the stock price of OOP-Research or the price of "WTI" oil.

After the NYSE closed, there is nothing difficult, because the latest DowJonesAverage30 is static until the next opening bell. But our web application want to display the updated data during the trading.
So we can say the latest DowJonesAverage30 is independent from the request, but not static. How can our Servlets handle this case? Assuming that we can access the SQL table somewhere in the world on which the latest DowJonesAverage30 is available. The easiest way is to lookup the SQL table on every request, as you know.
But is this the best way? While the latest DowJonesAverage30 is independent from the request, we are going to query it on each request. When 100 requests for the different stock prices are dispatched at almost the same time, the lookup for DowJonesAverage30 is made 100 times. But all the results are same! This is nothing more than performance reduction.

Go Site Map

The best place to live, ServletContext

To generate the data which is independent from the request, but not static, it is desirable that:

  • Some object in our web appliaction is responsible for getting the latest DowJonesAverage30 periodically. From now on, we call the object with this kind of function as self-update-object.
  • Our Servlet can access the self-update-object above to retrieve the latest DowJonesAverage30.
Using the instance of Thread, we can define the self-update-object above easily. At some time interval, it will query the latest data and update its field. Or, the latest data can be sent as JMS Message to self-update-object. Anyway, our Servlet can access the updated value of this field through getXX() method on the self-update-object.
By the way, where should we place such a self-update-object? One way is to put it as one of the class scoped instance variable of our Servlets. Unless our Servlets implement SingleThreadModel interface, only one instance per Servlet is created in the servlet container. This means the instance of the self-update-object is also unique in the container. I think this may not cause the problem. But we should always make our Servlets thread safe. The service( ) method (and doGet( ) or doPost( )) is invoked by the multiple threads simultaneouly when the a number of requests arrive at the same time. All of our Servlets must be capable of this situation. The simplest way to make our Servlets thread safe is to remove all the class scoped instance valiables. Because our self-update-object is independent from the request (it is nerver modified by the request and we can say that self-update-object itself is thread safe), putting it as the class scoped instance variable will do no harm. But, we like to find more confortable place, if we can.
In general, ServletContext is the place for the resources shared among all the Servlets which belong to the same context. And the reference to the external resources, for example the remote reference to EJB Home, can go there. We can say that any thread safe object can be stored into ServletContext. Then, why don't we place our self-update-object in ServletContext? It may be the best place to live for our self-update-object.

Self-update-object
Self-update-object in ServletContext

I've suggested the solution using the object which dispatches the new Thread. As far as I know, the current Servlet specification (Version2.2) does not prohibit this (not like EJB spec). The future spec may or may not prohibit the object in the ServletContext from dispacthing the new thread. So, if you take this design, please do it at your own risk.
Go Site Map

Example:

Self-update-object living ServletContext

I'll show the example of Self-update-object living ServletContext.
The ContextObject is very simple class for self-update-object. After startTimeStamp( ) is called, it add the instance of Date into the List every 10 seconds, untill stopTimeStamp( ).
And getTime( ) method returns the instance of List with Date instances.

/*
 *  ContextObject
 *
 * Created: Wed Oct 11 20:06:41 2000
 * $Revision$
 * Modified: $Date$
 *
 * Author: Jun Inamori
 *
 * Copyright (c) 1998-2000 Jun Inamori
 * All rights reserved.
 *
 */
import java.util.*;

/**
 * @author Jun Inamori
 */
public class ContextObject{

    private List list=new ArrayList();
    private Timer timer=null;
    private boolean isCont=true;

    public ContextObject() {

    }

    public void time(){
	Date some=new Date();
	list.add(some);
    }

    public List getTime(){
	return list;
    }

    public void startTimeStamp(){
	timer=new Timer();
	timer.start();
    }

    public void stopTimeStamp(){
	isCont=false;
	timer.interrupt();
    }

    class Timer extends Thread{

	public void run(){
	    while(isCont){
		try{
		    sleep(10000);
		}
		catch(InterruptedException ex){
		    interrupt();
		    break;
		}
		time();
	    }
	}

    }

} //End of : ContextObject


When "init()" is invoked, ContextObjectServlet creates ths instance of ContextObject and puts it in ServletContext. During the "doGet()" method, the instance of ContextObject is retrieved from ServletContext. The list of timestamp is available on it through "getTime()" method. ContextObjectServlet generates the HTML fragment for the table listing the timestamp.
/*
 *  ContextObjectServlet
 *
 * Created: Wed Oct 11 20:43:21 2000
 * $Revision$
 * Modified: $Date$
 *
 * Author: Jun Inamori
 *
 * Copyright (c) 1998-2000 Jun Inamori
 * All rights reserved.
 *
 */
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;

/**
 * @author Jun Inamori
 */
public class ContextObjectServlet
             extends HttpServlet{

    public void init(ServletConfig cnf)
	throws ServletException{
	super.init(cnf);
	ServletContext cnt=cnf.getServletContext();
	ContextObject obj=new ContextObject();
	obj.startTimeStamp();
	cnt.setAttribute("obj",obj);
	System.out.
            println("ConextObjectServlet.init()");
    }

    public void doGet(HttpServletRequest req,
                      HttpServletResponse res)
        throws IOException, ServletException{

	res.
        setContentType("text/html; charset=us-ascii");
        PrintWriter out = res.getWriter();
	out.println("<HTML>");
	out.println("<HEAD><TITLE>");
	out.println("ContextObject");
	out.println("</TITLE></HEAD>");
	out.println("");
	out.println("<BODY>");
	out.println("<CENTER>");
	ServletContext cnt=getServletContext();
	Object cobj=cnt.getAttribute("obj");
	if(cobj!=null){
	    ContextObject obj=(ContextObject)cobj;
	    List list=obj.getTime();
	    writeTimeTable(out,list);
	}
	else{
	    out.println("ContextObject not found!");
	}
	out.println("</CENTER>");
	out.println("</BODY></HTML>");
    }

    public void destroy(){
	ServletContext cnt=getServletContext();
	Object cobj=cnt.getAttribute("obj");
	if(cobj!=null){
	    ContextObject obj=(ContextObject)cobj;
	    obj.stopTimeStamp();
	    cnt.removeAttribute("obj");
	}
	System.out.
        println("ConextObjectServlet.destroy()");
    }

    private void writeTimeTable(PrintWriter out,
                                List list){

	int size=list.size();
	if(size!=0){
	    out.println("<TABLE BODER=\"1\">");
	    out.
            println("<TR><TH>Count</TH>
            <TH>Time</TH></TR>");
	    for(int i=0;i<size;i++){
		out.println("<TR>");
		out.println("<TD>");
		out.println((i+1)+"th time");
		out.println("</TD>");
		out.println("<TD>");
		out.println(((Date)list.get(i)).
                            toString());
		out.println("</TD>");
		out.println("</TR>");
	    }
	    out.println("</TABLE>");
	}
	else{
	    out.println("No timestamp!");	    
	}
    }

} //End of : ContextObjectServlet


Go Site Map

Caution!
All the APIs for Servlet/JSP introduced by this web site are now included in Bento framework:
  • Simpler than JSTL or Apache Struts
  • MVC framework by HTML
  • Input validation from CGI FORM
  • Easy user authentication
  • Easy localization (L10n)
To download the APIs and source code examples, please visit the web site of Bento framework.


JBuilder 2007


General Information

For Java Development

Java and all Java-based trademarks and logos are trademarks or registered of Sun Microsystems, Inc. in the United States and other countries.


ALL CONTENTS COPYRIGHT 1997-2007, OOP-Research Corporation. All rights reserved.