gamelan
Search EarthWeb
CodeGuru | Gamelan | Jars | Wireless | Discussions
Navigate developer.com
Architecture & Design  
Database  
Java
Languages & Tools
Microsoft & .NET
Open Source  
Project Management  
Security  
Techniques  
Voice  
Web Services  
Wireless/Mobile
XML  
Technology Jobs  

   Developer.com Webcasts:
  The Impact of Coding Standards and Code Reviews

  Project Management for the Developer

  Defining Your Own Software Development Methodology

  more Webcasts...




See the Winners!


Developer Jobs

Be a Commerce Partner
Corporate Gifts
Dental Insurance
Memory
Online Education
KVM Switch over IP
Online Shopping
Promos and Premiums
Data Center Solutions
Rackmount LCD Monitor
Remote Online Backup
Best Price
Promotional Gifts
Build a Server Rack
Compare Prices

 


Untitled table test
Register here for your free Internet.com membership to download your Justifying and Funding Infrastructure Investments report.

This independent report will help you make the case for your IT investments. Topics covered include:

Measuring Infrastructure Value
Justifying New Investments
Establishing an Infrastructure Value Chain and More.
Register now for your free Internet.com membership to download your complimentary Forrester report.
Limited Time Offer!
Developer News -
Sun Latest to Help App Vendors Get 'SasSy'    April 24, 2008
Ubuntu's 'Hardy' Cozy With Windows    April 24, 2008
The $4.6B Business of The Social    April 22, 2008
Office 2007 Fails The OOXML Test    April 22, 2008
Free Tech Newsletter -

Best Practices for Developing a Web Site: Checklists, Tips, Strategies & More. Download Exclusive eBook Now.

Serving it with Style Part II
By David Reilly

In this second part of  our tutorial on writing Java servlets, we'll examine how servlets can receive input in the form of parameters from a CGI request, such as the output of an HTML form. This allows our servlets to become truly interactive and to solicit information from the user. As an example, we'll look at a simple voting servlet, that keeps a tally of a yes/no response to a question and displays the results online.

The need for dynamic servlets

A great way to spice up a Web site composed of static, unchanging pages is to add dynamic content powered by Java servlets. Dynamic pages that respond to interaction with the user, or that change over time, offer big advantages for Web developers :

  • Gives Web site visitors greater control over interaction with a site
  • Reduces Web development work, as some content becomes automated and updates without human intervention.

Rather than using a series of static pages, Java servlets can augment an existing site, by providing forms that respond to user queries or record data. For example, a search form can display a list of relevant pages for a search query, giving the user greater control over his or her interaction with the Web site. Not all pages need to respond to an HTML form on a Web page though -- a "what's new" page or table of contents can display dynamic content that changes over time, based on changes to the Web site. By automating some of the human effort involved with creating and maintaining pages, significant time savings can be made.

Writing interactive servlets

In order to create interactive servlets, we must first be capable of providing the servlets with a source of input. In most cases this will be the actual Web visitor, but it could just as easily be another source of data (such as a database for a list of news items or a local file). The most important types of interaction, however, occur between people and servlets; so for the purpose of this tutorial, we'll concentrate primarily on Web visitors. To respond to users' requests, and establish interaction, a servlet must be capable of reading parameters.

The most important parameters that servlets have access to are those sent by the browser in a GET or POST request. When implementing a GET or POST request handler, servlets are passed an HttpServletRequest object, which contains these parameters. We can fetch parameters via the getParameter(String) method, or for multi-value parameters, getParameterValues(String) (see Listing 1).

Listing 1: Implementing a GET request

// Implement a "GET" request
public void doGet(<b>HttpServletRequest  request</b>,
                  HttpServletResponse response)
      throws ServletException, IOException
{
    // Set the content type to text/html
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();

    // Get the parameter 'username' from request
    String username = request.getParameter("username");

    if (username != null)
        out.println ("<H2>Hello there, " + username +
"</H2>);
    else
        out.println ("<H2>Who are you?</H2>");
}

Note that you should always check for the presence of parameters, rather than presuming they exist. A null value will be returned if the parameter does not exist, and any attempt at comparison (using String.equals() or String.compareTo() or string manipulation will generate a NullPointerException if the parameter was not present.

Getting initialization parameters

Another type of parameter that is useful for servlet development is an initialization parameter. This allows the webmaster to customize the functionality of a servlet, without recompilation of the Java servlet. This makes servlets more flexible and makes it less tempting for developers to "hard-wire" configuration details into the servlet. All servlets inherit a method, getInitParameter(String), which will return a configuration parameter in string format (see Listing 2).

Listing 2: Getting initialization parameters

public void doGet(HttpServletRequest  request,
                  HttpServletResponse response)
                  throws ServletException, IOException
{
    // Get initialization parameter
    String format = getInitParameter ("format");

    // Check to see if it is not null, and then compare
    if ( format == null ) format = "HTML";
    if ( format.equals ("HTML") )
    {
        // Set MIME content-type for response
        response.setContentType("text/html");
    }
    else
    {
        // Set MIME content-type for response
        response.setContentType("text/plain");
    }

    // ................         
}

Putting it all together with a practical example

To demonstrate the reading of parameters and dynamic page generation, I've written a simple voting servlet, that displays an online survey and maintains a tally of the results. Though the example itself is simplistic, it does demonstrate several key points

  • reading of CGI and initialization parameters
  • generation of a dynamic page that changes based on user actions
  • multi-threaded servlets.

As discussed earlier, input parameters make it possible to create dynamic pages that change in response to users. However, an important consideration that must be addressed by servlet developers is that multiple users will be interacting with a servlet concurrently. Like any multi-threaded application, there is a vital need to take care when multiple servlet instances access and modify data concurrently. Why? Because unless care is taken to restrict updates, two or more instances can overwrite each other's modifications, and counters can become inaccurate.

One strategy for dealing with multiple threads of execution accessing and modifying data concurrently is to restrict read and write access to data to only one thread at any point in time. This strategy is used in our voting example, where access to vote tallies are provided by accessor methods. Accessor methods provide a controlled access to member variables and, in this case, are marked with the synchronized keyword to prevent concurrent access (see Listing 3).

Listing 3: Restricting read and write access to data to one thread at a time

// Static variables shared by all instances of VotingServlet
private static int VOTE_YES = 0;
private static int VOTE_NO  = 0;
private static int VOTE_UND = 0;

// Accessor methods to access member variables
public synchronized int getYes()
{
    return VOTE_YES;
}

// Acccessor methods to modify member variables
public synchronized void incYes()
{
    VOTE_YES++;
}

Our voting servlet implements both GET and POST methods. When first executed via a GET method, the servlet outputs an HTML form, showing the voting question (controlled by an initialization parameter) and a list of three radio-button choices. Figure 1 shows the output of the GET method.

Figure 1

Figure 1. GET method of voting servlet displays form

The output of this HTML form could be sent to a GET or a POST method. However, to distinguish between the action of displaying the voting question and displaying the results, I've chosen to redirect output to the POST method and have the GET method be responsible for outputting the form. Another alternative is to embed a hidden field parameter in a form and to display a form if the parameter isn't present. This allows developers to implement only a single method, rather than GET and POST. Figure 2 shows a sample view of the voting servlet, after some votes have been cast.

Figure 2

Figure 2. POST method of voting servlet displays tally

Source code for VotingServlet

Listing 4: Source code for voting servlet

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

//
//
// VotingServlet
//
//
public class VotingServlet extends HttpServlet
{
        // Static variables shared by all instances of VotingServlet
        private static int VOTE_YES = 0;
        private static int VOTE_NO  = 0;
        private static int VOTE_UND = 0;

        public void doGet(HttpServletRequest  request,
                              HttpServletResponse response)
                                          throws ServletException, IOException
        {
                // Set MIME content-type for response
                response.setContentType("text/html");

                // Obtain a print writer to output our HTML form
                PrintWriter out = response.getWriter();

                // Output header
                out.println ("<H4 ALIGN=CENTER><FONT
COLOR='GREEN'>Online Voting Servlet</FONT></H4><HR
COLOR='GREEN'>");
                
                // Get initialization parameter
                String question = getInitParameter ("question");
        
                // Output question
                out.println ("<H3> " + question + "
</H3>");

                // Output HTML form
                out.println ("<FORM ACTION='" +
request.getServletPath() + "' METHOD=POST>");
                out.println ("<PRE>");
                out.println ("     <B> <input type=radio
name='vote' value='yes'> YES");
                out.println ("     <B> <input type=radio
name='vote' value='no' > NO");
                out.println ("     <B> <input type=radio
name='vote' value='und' checked> UNDECIDED");
                out.println ("<input type=submit>");
                out.println ("</PRE></FORM>");

                // Output footer
                out.println ("<HR COLOR='GREEN'>");

                out.close();
        }

        public void doPost(HttpServletRequest  request,
                               HttpServletResponse response)
                                          throws ServletException, IOException
        {
                // Set MIME content-type for response
                response.setContentType("text/html");

                // Obtain a print writer to output our HTML form
                PrintWriter out = response.getWriter();

                // Output header
                out.println ("<HEAD><TITLE>Voting
Results</TITLE></HEAD>");
                out.println ("<H4 ALIGN=CENTER><FONT
COLOR='GREEN'>Online Voting Servlet</FONT></H4><HR
COLOR='GREEN'>");
                
                // Get initialization parameter
                String question = getInitParameter ("question");
        
                // Output question
                out.println ("<H3> " + question + "
</H3>");

                // Get vote from HTML form
                String vote = request.getParameter ("vote");

                // Default to undecided if no vote cast
                if (vote == null) vote="und";

                // Increment appropriate vote counter
                if (vote.equals ("yes")) incYes();
                if (vote.equals ("no"))  incNo();
                if (vote.equals ("und")) incUndecided();

                // Output table of results
                out.println ("<TABLE BORDER=1 WIDTH=40%>");
                out.println ("<TR> <TD> <H4> Results
</H4> </TD> </TR>");
                out.println ("<TR> <TD> YES </TD>
<TD> " + getYes() + " </TD> </TR>");
                out.println ("<TR> <TD> NO </TD>
<TD> " + getNo() + " </TD> </TR>");
                out.println ("<TR> <TD> UNDECIDED
</TD> <TD> " + getUndecided() + " </TD>
</TR>");
                out.println ("</TABLE>");


                // Output footer
                out.println ("<HR COLOR='GREEN'>");

                out.close();

        }

        // Accessor methods to access member variables
        public synchronized int getYes()
        {
                return VOTE_YES;
        }

        // Accessor methods to access member variables
        public synchronized int getNo()
        {
                return VOTE_NO;
        }

        // Accessor methods to access member variables
        public synchronized int getUndecided()
        {
                return VOTE_UND;
        }

        // Acccessor methods to modify member variables
        public synchronized void incYes()
        {
                VOTE_YES++;
        }

        // Acccessor methods to modify member variables
        public synchronized void incNo()
        {
                VOTE_NO++;
        }

        // Acccessor methods to modify member variables
        public synchronized void incUndecided()
        {
                VOTE_UND++;
        }

        // Return name of servlet
        public String getServletInfo() 
        {
                return "VotingServlet";
        }
}

Configuring initialization parameters

The voting servlet uses an initialization parameter to specify the question to be voted on. Setting initialization parameters like this varies, depending on the type of servlet engine or Web server used. However, if you're using the servletrunner engine, it's a relatively straightforward process to configure.

  1. Edit the servlet.properties file and add the following entries

    servlet.voting.code=VotingServlet
    servlet.voting.initArgs=question="Are servlets cool or what?"
  2. Compile VotingServlet.java and copy it across to the JSDK/examples directory.
  3. Start servletrunner, and execute the servlet.

    eg - http://localhost:8080/servlet/voting  

Summary

Creating dynamic servlets that respond to user interaction is really easy and often far simpler than alternatives offered by scripting languages (many of which require you to write or use a third-party CGI parser). Additionally, servlets support initialization parameters, which allow servlets to be easily customized, without modifying any source code or recompiling the software. This offers a substantial advantage over Perl CGI scripts, which almost always need customization to remove hard-coded path information or configuration details.

Code for this article

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

//
//
// VotingServlet
//
//
public class VotingServlet extends HttpServlet
{
	// Static variables shared by all instances of VotingServlet
	private static int VOTE_YES = 0;
	private static int VOTE_NO  = 0;
	private static int VOTE_UND = 0;

	public void doGet(HttpServletRequest  request,
		              HttpServletResponse response)
					  throws ServletException, IOException
	{
		// Set MIME content-type for response
		response.setContentType("text/html");

		// Obtain a print writer to output our HTML form
		PrintWriter out = response.getWriter();

		// Output header
		out.println ("<H4 ALIGN=CENTER><FONT COLOR='GREEN'>Online Voting Servlet</FONT></H4><HR COLOR='GREEN'>");
		
		// Get initialization parameter
		String question = getInitParameter ("question");
	
		// Output question
		out.println ("<H3> " + question + " </H3>");

		// Output HTML form
		out.println ("<FORM ACTION='" + request.getServletPath() + "' METHOD=POST>");
		out.println ("<PRE>");
		out.println ("     <B> <input type=radio name='vote' value='yes'> YES");
		out.println ("     <B> <input type=radio name='vote' value='no' > NO");
		out.println ("     <B> <input type=radio name='vote' value='und' checked> UNDECIDED");
		out.println ("<input type=submit>");
		out.println ("</PRE></FORM>");

		// Output footer
		out.println ("<HR COLOR='GREEN'>");

		out.close();
	}

	public void doPost(HttpServletRequest  request,
		               HttpServletResponse response)
					  throws ServletException, IOException
	{
		// Set MIME content-type for response
		response.setContentType("text/html");

		// Obtain a print writer to output our HTML form
		PrintWriter out = response.getWriter();

		// Output header
		out.println ("<HEAD><TITLE>Voting Results</TITLE></HEAD>");
		out.println ("<H4 ALIGN=CENTER><FONT COLOR='GREEN'>Online Voting Servlet</FONT></H4><HR COLOR='GREEN'>");
		
		// Get initialization parameter
		String question = getInitParameter ("question");
	
		// Output question
		out.println ("<H3> " + question + " </H3>");

		// Get vote from HTML form
		String vote = request.getParameter ("vote");

		// Default to undecided if no vote cast
		if (vote == null) vote="und";

		// Increment appropriate vote counter
		if (vote.equals ("yes")) incYes();
		if (vote.equals ("no"))  incNo();
		if (vote.equals ("und")) incUndecided();

		// Output table of results
		out.println ("<TABLE BORDER=1 WIDTH=40%>");
		out.println ("<TR> <TD> <H4> Results </H4> </TD> </TR>");
		out.println ("<TR> <TD> YES </TD> <TD> " + getYes() + " </TD> </TR>");
		out.println ("<TR> <TD> NO </TD> <TD> " + getNo() + " </TD> </TR>");
		out.println ("<TR> <TD> UNDECIDED </TD> <TD> " + getUndecided() + " </TD> </TR>");
		out.println ("</TABLE>");


		// Output footer
		out.println ("<HR COLOR='GREEN'>");

		out.close();

	}

	// Accessor methods to access member variables
	public synchronized int getYes()
	{
		return VOTE_YES;
	}

	// Accessor methods to access member variables
	public synchronized int getNo()
	{
		return VOTE_NO;
	}

	// Accessor methods to access member variables
	public synchronized int getUndecided()
	{
		return VOTE_UND;
	}

	// Acccessor methods to modify member variables
	public synchronized void incYes()
	{
		VOTE_YES++;
	}

	// Acccessor methods to modify member variables
	public synchronized void incNo()
	{
		VOTE_NO++;
	}

	// Acccessor methods to modify member variables
	public synchronized void incUndecided()
	{
		VOTE_UND++;
	}

    // Return name of servlet
	public String getServletInfo() 
	{
		return "VotingServlet";
	}
}


About the author

David Reilly is a software engineer and freelance technical writer living in Australia. A Sun Certified Java 1.1 Programmer, his research interests includes the Java programming language and networking & distributed systems. He can be reached via email at java@davidreilly.com.



Tools:
Add www.developer.com to your favorites
Add www.developer.com to your browser search box
IE 7 | Firefox 2.0 | Firefox 1.5.x
Receive news via our XML/RSS feed


Java Archives

Data Sheet: IBM Information Server Blade
Generate Complete .NET Web Apps in Minutes . Download Iron Speed Designer today.
Best Practices for Developing a Web Site. Checklists, Tips & Strategies. Download Exclusive eBook Now.
Whitepaper: Enterprise Information Integration--Deployment Best Practices for Low-Cost Implementation
Developing Intelligent Communications? Visit the Avaya DevConnect Center on DevX.



JupiterOnlineMedia

internet.comearthweb.comDevx.commediabistro.comGraphics.com

Search:

Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

Jupitermedia Corporate Info


Legal Notices, Licensing, Reprints, & Permissions, Privacy Policy.

Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers

Solutions
Whitepapers and eBooks
Microsoft Article: HyperV-The Killer Feature in WinServer ‘08
Avaya Article: How to Feed Data into the Avaya Event Processor
Microsoft Article: Install What You Need with Win Server ‘08
HP eBook: Putting the Green into IT
Whitepaper: HP Integrated Citrix XenServer for HP ProLiant Servers
Intel Go Parallel Portal: Interview with C++ Guru Herb Sutter, Part 1
Intel Go Parallel Portal: Interview with C++ Guru Herb Sutter, Part 2--The Future of Concurrency
Avaya Article: Setting Up a SIP A/S Development Environment
IBM Article: How Cool Is Your Data Center?
Microsoft Article: Managing Virtual Machines with Microsoft System Center
HP eBook: Storage Networking , Part 1
Microsoft Article: Solving Data Center Complexity with Microsoft System Center Configuration Manager 2007
MORE WHITEPAPERS, EBOOKS, AND ARTICLES
Webcasts
Intel Video: Are Multi-core Processors Here to Stay?
On-Demand Webcast: Five Virtualization Trends to Watch
HP Video: Page Cost Calculator
Intel Video: APIs for Parallel Programming
HP Webcast: Storage Is Changing Fast - Be Ready or Be Left Behind
Microsoft Silverlight Video: Creating Fading Controls with Expression Design and Expression Blend 2
MORE WEBCASTS, PODCASTS, AND VIDEOS
Downloads and eKits
Sun Download: Solaris 8 Migration Assistant
Sybase Download: SQL Anywhere Developer Edition
Red Gate Download: SQL Backup Pro and free DBA Best Practices eBook
Red Gate Download: SQL Compare Pro 6
Iron Speed Designer Application Generator
MORE DOWNLOADS, EKITS, AND FREE TRIALS
Tutorials and Demos
How-to-Article: Preparing for Hyper-Threading Technology and Dual Core Technology
eTouch PDF: Conquering the Tyranny of E-Mail and Word Processors
IBM Article: Collaborating in the High-Performance Workplace
HP Demo: StorageWorks EVA4400
Intel Featured Algorhythm: Intel Threading Building Blocks--The Pipeline Class
Microsoft How-to Article: Get Going with Silverlight and Windows Live
MORE TUTORIALS, DEMOS AND STEP-BY-STEP GUIDES