Servlets





Servlets

On the server side, we're not ready to accept an XML-RPC or SOAP request yet because that would require parsing an input XML document. I'll take that up beginning in Chapter 5. On the other hand, we are completely ready to respond to a CGI request with an XML document. Because this is a book about Java, I'll use servlets to do this. The user will connect to a known URL. The query string component will include a field asking for a certain number of Fibonacci numbers. The servlet will calculate that number and return it as an XML document with an attached stylesheet.

The query string will include a single generations field whose value is the index of the last Fibonacci number you want. For example, for a servlet installed at http://www.elharo.com/fibonacci, you'd ask for 42 Fibonacci numbers by loading the URL http://www.elharo.com/fibonacci?generations=42.

The servlet engine handles the HTTP header and all other interactions with the client. To change any of the details, you would use the HttpServletRequest and HttpServletResponse objects passed as arguments to the doGet() method (for HTTP GET) or doPost() (for HTTP POST). This example behaves the same for both POST and GET—the doPost() method will just call the doGet() method.

For input, it's easy to read the query string field from a servlet using the getParameter() and getParameters() methods. These handle all necessary decoding of x-www-form-urlencoded values. If the query string has more than one field with the specified name, then getParameter() returns the value of the first one. getParameters() returns an array of all the field values for fields with a certain name. In this case, I'll be satisfied with just the first field named generations, so I'll choose getParameter(). Because the getParameter() method effectively hides whether the query string was included in the URL sent by the GET method or in the body sent by the POST method, adding support for POST to this servlet is very easy: simply implement the doPost() method and pass its argument to the doGet() method.

For output, we just need to set the content type to text/xml and write the response on the PrintWriter returned by the HttpServletResponse's getWriter() method. By default, this PrintWriter uses the ISO-8859-1 encoding. If you want to use another encoding, such as UTF-8, you must adjust the MIME type to reflect that. For example, to send data in UTF-16, you set the MIME type to text/xml; charset=UTF-16. Figure shows the completed servlet.

12 A Servlet That Generates XML
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.math.BigInteger;


public class FibonacciServlet extends HttpServlet {

  public void doGet(
   HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {


    //read the query string
    int numberOfGenerations = 10;
    String generations = request.getParameter("generations");
    try {
      numberOfGenerations = Integer.parseInt(generations);
    }
    catch (Exception e) {// NumberFormat or NullPointerException
      // use default value of 10
    }

    response.setContentType("text/xml; charset=UTF-8");
    PrintWriter out = response.getWriter();

    out.println("<?xml version=\"1.0\"?>");
    out.print  ("<?xml-stylesheet ");
    out.println(
     "type='text/css' href='/xml/styles/fibonacci.css'?>");
    out.println("<Fibonacci_Numbers>");

    BigInteger low  = BigInteger.ONE;
    BigInteger high = BigInteger.ONE;
    for (int i = 1; i <= numberOfGenerations; i++) {
      out.print("  <fibonacci index=\"" + i + "\">");
      out.print(low);
      out.println("</fibonacci>");

      BigInteger temp = high;
      high = high.add(low);
      low = temp;
    }
    out.println("</Fibonacci_Numbers>");

    out.close();

  }

  public void doPost(
   HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {

    doGet(request, response);

  }

}

Once you've compiled this servlet, you'll need to install it on your server. Details vary a little from servlet engine to servlet engine. I use the Apache Jakarta Project's Tomcat [http://www.jakarta.apache.org/tomcat], which is the official reference implementation of the Java Servlet API. If you're using something different, please consult your documentation.

To install the servlet into Tomcat, first upload the FibonacciServlet.class file into your WEB-INF/classes directory. This makes it accessible at a URL based on the class name, such as http://www.elharo.com:8080/servlet/FibonacciServlet. Here http://www.elharo.com:8080 is the URL for my servlet context. (Yours of course will be something different.) servlet is the part of the URL that tells the servlet engine it should expect to load a servlet by its class name, and FibonacciServlet is the name of the servlet class.

If you wanted the servlet to be accessible by a more convenient name, you would edit the web.xml file in the servlet context directory to map that name to the class name. For example, the following lines map the FibonacciServlet class to the URL http://www.elharo.com:8080/chapter3:

<servlet> 
 <servlet-name>fibonacci</servlet-name>
 <servlet-class>FibonacciServlet</servlet-class>
</servlet>

<servlet-mapping>
  <servlet-name>fibonacci</servlet-name>
  <url-pattern>chapter3</url-pattern>
</servlet-mapping>

In Tomcat 3.2 and earlier, you must shut down and restart the servlet engine for Tomcat to recognize that the web.xml file has changed and use the new mapping.

Note

For more details about servlets, web.xml, Tomcat, and related topics, you might wish to consult the reference I used when writing this chapter: Inside Servlets, Second Edition. D. R. Callaway. Boston: Addison-Wesley. 2001. ISBN 0-201-70906-6.



     Python   SQL   Java   php   Perl 
     game development   web development   internet   *nix   graphics   hardware 
     telecommunications   C++ 
     Flash   Active Directory   Windows