Site hosted by Angelfire.com: Build your free website today!

Prerequisite :: Core Java

Java Servlets

a servlet is a generic server extension--a Java class that can be loaded dynamically to expand the functionality of a server. Servlets are commonly used with web servers, where they can take the place of CGI scripts. A servlet is similar to a proprietary server extension, except that it runs inside a Java Virtual Machine (JVM) on the server , so it is safe and portable. Servlets operate solely within the domain of the server: unlike applets, they do not require support for Java in the web browser.

Standalone Servlet Engines

A standalone engine is a server that includes built-in support for servlets. Such an engine has the advantage that everything works right out of the box. One disadvantage, however, is that you have to wait for a new release of the web server to get the latest servlet support. Because servlets are still fairly new, this sort of server is still a bit of a rarity. As the various vendors upgrade their web servers, we expect that many of the servers will provide built-in support for servlets.

Standalone engines in web servers include the following:

Application servers are a fertile new area of development. An application server offers server-side support for developing enterprise-based applications. Here are two application servers that include servlet engines:

The most popular Servlet engine is Apache's Tomcat (v 5.0)

Servlet API

We can move on and talk about the Servlet API that you'll be using to create HTTP servlets, or any kind of servlets, for that matter. Servlets use classes and interfaces from two packages: javax.servlet and javax.servlet.http . The javax.servlet package contains classes to support generic, protocol-independent servlets. These classes are extended by the classes in the javax.servlet.http package to add HTTP-specific functionality. The top-level package name is javax instead of the familiar java, to indicate that the Servlet API is a standard extension.

Every servlet must implement the javax.servlet.Servlet interface. Most servlets implement it by extending one of two special classes: javax. servlet.GenericServlet or javax.servlet.http.HttpServlet . A protocol-independent servlet should subclass GenericServlet, while an HTTP servlet should subclass HttpServlet, which is itself a subclass of GenericServlet with added HTTP-specific functionality.

Before running any program  install Tomcat Server & configure it correctly. There are many tutorials on net to configure Tomcat. Go through them.

Example  A servlet that prints "Hello World"

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

public class HelloWorld extends HttpServlet {

  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>Hello World</TITLE></HEAD>");
    out.println("<BODY>");
    out.println("<BIG>Hello World</BIG>");
    out.println("</BODY></HTML>");
  }
}

This servlet extends the HttpServlet class and overrides the doGet() method inherited from it. Each time the web server receives a GET request for this servlet, the server invokes this doGet() method, passing it an HttpServletRequest object and an HttpServletResponse object.

The HttpServletRequest represents the client's request. This object gives a servlet access to information about the client, the parameters for this request, the HTTP headers passed along with the request, and so forth.

The HttpServletResponse represents the servlet's response. A servlet can use this object to return data to the client. This data can be of any content type, though the type should be specified as part of the response. A servlet can also use this object to set HTTP response headers.

Our servlet first uses the setContentType() method of the response object to set the content type of its response to "text/html", the standard MIME content type for HTML pages. Then, it uses the getWriter() method to retrieve a PrintWriter , the international-friendly counterpart to a PrintStream. PrintWriter converts Java's Unicode characters to a locale-specific encoding. For an English locale, it behaves same as a PrintStream. Finally, the servlet uses this PrintWriter to send its "Hello World" HTML to the client.

That's it! That's all the code needed to say hello to everyone who "surfs" to our servlet.

Handling Form Data

The "Hello World" servlet is not very exciting, so let's try something slightly more ambitious. This time we'll create a servlet that greets the user by name. It's not hard. First, we need an HTML form that asks the user for his or her name. The following page should suffice:

<HTML>
<HEAD>
<TITLE>Introductions</TITLE>
</HEAD>
<BODY>
<FORM METHOD=GET ACTION="/servlet/Hello">
If you don't mind me asking, what is your name?
<INPUT TYPE=TEXT NAME="name"><P>
<INPUT TYPE=SUBMIT>
</FORM>
</BODY>
</HTML>

Example A servlet that knows to whom it's saying hello

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

public class Hello extends HttpServlet {

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

    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    String name = req.getParameter("name");
    out.println("<HTML>");
    out.println("<HEAD><TITLE>Hello, " + name + "</TITLE></HEAD>");
    out.println("<BODY>");
    out.println("Hello, " + name);
    out.println("</BODY></HTML>");
  }

  public String getServletInfo() {
    return "A servlet that knows the name of the person to whom it's" +
           "saying hello";
  }
}

This servlet is nearly identical to the HelloWorld servlet. The most important change is that it now calls req.getParameter("name") to find out the name of the user and that it then prints this name instead of the harshly impersonal (not to mention overly broad) "World". The getParameter() method gives a servlet access to the parameters in its query string. It returns the parameter's decoded value or null if the parameter was not specified. If the parameter was sent but without a value, as in the case of an empty form field, getParameter() returns the empty string.

This servlet also adds a getServletInfo() method. A servlet can override this method to return descriptive information about itself, such as its purpose, author, version, and/or copyright. It's akin to an applet's getAppletInfo() . The method is used primarily for putting explanatory information into a web server administration tool. You'll notice we won't bother to include it in future examples because it is clutter for learning.

Handling POST Requests

You've now seen two servlets that implement the doGet() method. Now let's change our Hello servlet so that it can handle POST requests as well. Because we want the same behavior with POST as we had for GET, we can simply dispatch all POST requests to the doGet() method with the following code:

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

Now the Hello servlet can handle form submissions that use the POST method:

<FORM METHOD=POST ACTION="/servlet/Hello">

In general, it is best if a servlet implements either doGet() or doPost(). Deciding which to implement depends on what sort of requests the servlet needs to be able to handle, as discussed earlier. The code you write to implement the methods is almost identical. The major difference is that doPost() has the added ability to accept large amounts of input.

Request Parameters

Each access to a servlet can have any number of request parameters associated with it. These parameters are typically name/value pairs that tell the servlet any extra information it needs to handle the request. Please don't confuse these request parameters with init parameters, which are associated with the servlet itself.

An HTTP servlet gets its request parameters as part of its query string (for GET requests) or as encoded post data (for POST requests). A servlet used as a server-side include has its parameters supplied by <PARAM> tags. Other types of servlets can receive their parameters in other ways.

Fortunately, even though a servlet can receive parameters in a number of different ways, every servlet retrieves its parameters the same way, using getParameter() and getParameterValues() :

public String ServletRequest.getParameter(String name)
public String[] ServletRequest.getParameterValues(String name)

getParameter() returns the value of the named parameter as a String or null if the parameter was not specified. The value is guaranteed to be in its normal, decoded form. If the parameter has multiple values, the value returned is server-dependent. If there's any chance a parameter could have more than one value, you should use the getParameterValues() method instead. This method returns all the values of the named parameter as an array of String objects or null if the parameter was not specified. A single value is returned in an array of length 1.

The getParameter() method was deprecated in the Java Web Server 1.1 in favor of getParameterValues(). However, after quite a lot of public protest, Sun took getParameter() off the deprecation list in the final release of Servlet API 2.0. It was the first Java method to be undeprecated!

One word of warning: if the parameter information came in as encoded POST data, it may not be available if the POST data has already been read manually using the getReader() or getInputStream() method of ServletRequest (because POST data can be read only once).

The possible uses for request parameters are unlimited. They are a general-purpose way to tell a servlet what to do, how to do it, or both. For a simple example, let's look at how a dictionary servlet might use getParameter() to find out the word it needs to look up.

An HTML file could contain this form asking the user for a word to look up:

<FORM METHOD=GET ACTION="/servlet/Dictionary">
Word to look up: <INPUT TYPE=TEXT NAME="word"><P>
Another word? <INPUT TYPE=TEXT NAME="word"><P>
<INPUT TYPE=SUBMIT><P>
</FORM>

Or the HTML file could contain this server-side include:

<SERVLET CODE=Dictionary>
<PARAM NAME=word VALUE=obfuscate>
<PARAM NAME=word VALUE=onomatopoeia>
</SERVLET>

No matter what the HTML looks like or whether the servlet handles GET requests, POST requests, or server-side include requests or is part of a filter chain, you can use code like the following to retrieve the servlet's parameters:

String word = req.getParameter("word");
String definition = getDefinition(word);
out.println(word + ": " + definition);

While this code works fine, it can handle only one word per request. To handle multiple values for word, the servlet can use the getParameterValues() method instead:

String[] words = req.getParameterValues("word");
if (words != null) {
  for (int i = 0; i < words.length; i++) {
    String definition = getDefinition(words[i]);
    out.println(words[i] + ": " + definition);
    out.println("<HR>");
  }
}

In addition to getting parameter values, a servlet can access parameter names using getParameterNames() :

public Enumeration ServletRequest.getParameterNames()

This method returns all the parameter names as an Enumeration of String object or an empty Enumeration if the servlet has no parameters. The method is most often used for debugging.

Finally, a servlet can retrieve the raw query string of the request with getQueryString():

public String ServletRequest.getQueryString()

This method returns the raw query string (encoded GET parameter information) of the request or null if there was no query string. This low-level information is rarely useful for handling form data. It's best for handling a single unnamed value, as in "/servlet/Sqrt?576", where the returned query string is "576".

Example shows the use of these methods with a servlet that prints its query string, then prints the name and value for all its parameters.

Snooping parameters

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

public class ParameterSnoop extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();

    out.println("Query String:");
    out.println(req.getQueryString());
    out.println();

    out.println("Request Parameters:");
    Enumeration enum = req.getParameterNames();
    while (enum.hasMoreElements()) {
      String name = (String) enum.nextElement();
      String values[] = req.getParameterValues(name);
      if (values != null) {
        for (int i = 0; i < values.length; i++) {
          out.println(name + " (" + i + "): " + values[i]);
        }
      }
    }
  }

Sending a Normal Response

Let's begin our discussion of servlet responses with another look at the first servlet in this book, the HelloWorld servlet, shown in Example.

Example Hello again

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

public class HelloWorld extends HttpServlet {

  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>Hello World</TITLE></HEAD>");
    out.println("<BODY>");
    out.println("<BIG>Hello World</BIG>");
    out.println("</BODY></HTML>");
  }
}

This servlet uses two methods and a class that have been only briefly mentioned before. The setContentType() method of ServletResponse sets the content type of the response to be the specified type:

public void ServletResponse.setContentType(String type)

In an HTTP servlet, this method sets the Content-Type HTTP header.

The getWriter() method returns a PrintWriter for writing character-based response data:

public PrintWriter ServletResponse.getWriter() throws IOException

The writer encodes the characters according to whatever charset is given in the content type. If no charset is specified, as is generally the case, the writer uses the ISO-8859-1 (Latin-1) encoding appropriate for Western European languages.  so for now just remember that it's good form to always set the content type before you get a PrintWriter. This method throws an IllegalStateException if getOutputStream() has already been called for this response; it throws an UnsupportedEncodingException if the encoding of the output stream is unsupported or unknown.

In addition to using a PrintWriter to return a response, a servlet can use a special subclass of java.io.OutputStream to write binary data--the ServletOutputStream, which is defined in javax.servlet. You can get a ServletOutputStream with getOutputStream():

public ServletOutputStream ServletResponse.getOutputStream() throws IOException

This method returns an ServletOutputStream for writing binary (byte-at-a-time) response data. No encoding is performed. This method throws an IllegalStateException if getWriter() has already been called for this response.

The ServletOutputStream class resembles the standard Java PrintStream class. In the Servlet API Version 1.0, this class was used for all servlet output, both textual and binary. In the Servlet API Version 2.0, however, it has been relegated to handling binary output only. As a direct subclass of OutputStream, it makes available the write(), flush(), and close() methods of the OutputStream class. To these it adds its own print() and println() methods for writing most of the primitive Java data types. The only difference between the ServletOutputStream interface and that of a PrintStream is that the print() and println() methods of ServletOutputStream inexplicably cannot directly print parameters of type Object or char[].

Session-Tracking Basics

Session tracking is wonderfully elegant. Every user of a site is associated with a javax.servlet.http.HttpSession object that servlets can use to store or retrieve information about that user. You can save any set of arbitrary Java objects in a session object. For example, a user's session object provides a convenient location for a servlet to store the user's shopping cart contents.

A servlet uses its request object's getSession() method to retrieve the current HttpSession object:

public HttpSession HttpServletRequest.getSession(boolean create)

This method returns the current session associated with the user making the request. If the user has no current valid session, this method creates one if create is true or returns null if create is false. To ensure the session is properly maintained, this method must be called at least once before any output is written to the response.

You can add data to an HttpSession object with the putValue() method:

public void HttpSession.putValue(String name, Object value)

This method binds the specified object value under the specified name. Any existing binding with the same name is replaced. To retrieve an object from a session, use getValue():

public Object HttpSession.getValue(String name) 

This methods returns the object bound under the specified name or null if there is no binding. You can also get the names of all of the objects bound to a session with getValueNames():

public String[] HttpSession.getValueNames() 

This method returns an array that contains the names of all objects bound to this session or an empty (zero length) array if there are no bindings. Finally, you can remove an object from a session with removeValue():

public void HttpSession.removeValue(String name) 

This method removes the object bound to the specified name or does nothing if there is no binding. Each of these methods can throw a java.lang.IllegalStateException if the session being accessed is invalid (we'll discuss invalid sessions in an upcoming section).

A Hit Count Using Session Tracking

Following example shows a simple servlet that uses session tracking to count the number of times a client has accessed it, as shown in Figure. The servlet also displays all the bindings for the current session, just because it can.

Example  Session tracking : a hit count

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

public class SessionTracker extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();

    // Get the current session object, create one if necessary
    HttpSession session = req.getSession(true);

    // Increment the hit count for this page. The value is saved
    // in this client's session under the name "tracker.count".
    Integer count = (Integer)session.getValue("tracker.count");
    if (count == null)
      count = new Integer(1);
    else
      count = new Integer(count.intValue() + 1);
    session.putValue("tracker.count", count);

    out.println("<HTML><HEAD><TITLE>SessionTracker</TITLE></HEAD>");
    out.println("<BODY><H1>Session Tracking Demo</H1>");

    // Display the hit count for this page
    out.println("You've visited this page " + count + 
      ((count.intValue() == 1) ? " time." : " times."));

    out.println("<P>");

    out.println("<H2>Here is your session data:</H2>");
    String[] names = session.getValueNames();
    for (int i = 0; i < names.length; i++) {
      out.println(names[i] + ": " + session.getValue(names[i]) + "<BR>");
    }
    out.println("</BODY></HTML>");
  }

 


About

Mail

Main Page



CopyLeft 2004 Arvind Mohan Sharma