- Objectives
- Introduction
- Overriding HttpServlet GET, POST, and PUT Methods
- Triggering HttpServlet GET, POST, and PUT Methods
- Interfacing with HTML Requests
- Web Application Scope
- Servlet Life-cycle
- Using a RequestDispatcher
- Web Application Context
- Context Within a Distributable Web Application
- Chapter Summary
- Apply Your Knowledge
Introduction
JSP and servlets have greatly enhanced the way in which you can create and manage Web pages. The difficulty level of coding JSP is between that of coding HTML and pure Java. Servlets are pure Java. The idea behind having both is providing a way for non-programmers to contribute functionality through JSP. You can "program" a JSP page almost as easily as you can write an HTML page. For simple tasks like displaying the current date, you write a normal HTML page and add only a small amount of Java as a scriptlet. For big tasks like processing a shopping cart, you use JSP as the mediator between the Web form and a component(s) (bean or servlet) that has all the horsepower. Most of the code in a Web application will go into servlets. The JSP portion is a soft front end to the application that, typically, marketing can use comfortably.
There is a lot that happens when a servlet is invoked. This chapter covers much material that explains each step of the process. At this point, it will help to provide an overview of what happens in a typical JSP/servlet request. The sequence of events starts with a browser sending a request to a Web server. The server hands the request to a Servlet Container. The container loads the servlet (if it isn't already loaded), instantiates a request and response objects, and then hands these objects to the servlet by calling first its init() method, then its service() method, and lastly the destroy() method. The service() method will typically call one of the doXXX() methods such as doGet().
All these steps are covered in detail later in this chapter. Presently, just review the overall process presented in Figure 4.1.
Let's study an example of a servlet. The following is a fully functioning, albeit trivial, servlet example. Listing 4.1 represents all that is required to have a complete servlet.
Figure 4.1 Servlet handling of an HTTP Request.
Listing 4.1 The Source Code of a Minimum Servlet
/* SimpleServletExample.java, v 1.0 * */ import java.io.*; import javax.servlet.*; import javax.servlet.http.*; /** * A simple servlet. * SCWCD Exam Objective 1.1 = doGet(), doPost(), doPut() * * @author Reader@Que */ public class SimpleServletExample extends HttpServlet { // doGet() - SCWCD Exam Objective 1.1 public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { // set the MIME type response.setContentType("text/html"); // use this to print to browser PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title> A simple servlet. </title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>Simple Servlet</h1>"); out.println("This is a trivial " + "example of a servlet."); out.println("</body>"); out.println("</html>"); } }
Listing 4.1 showed you an example of a servlet. The code is ordinary, but notice one small thing about printing to the browser. This example uses PrintWriter instead of using ServletOutputStream. The former is used for text, while the latter is used for bytes. See Figure 4.2 for a picture of the output. Listing 4.2 is the HTML the servlet generates and sends to the browser.
Listing 4.2 The Source Code Returned to the Browser by Listing 4.1
<html> <head> <title> A simple servlet. </title> </head> <body> <h1>Simple Servlet</h1> This is a trivial example of a servlet. </body> </html>
The HTML in Listing 4.2 is rendered by a browser so that it looks like Figure 4.2.
Figure 4.2 You can create dynamic content using a servlet.
You write a servlet and compile it, and then place it in the appropriate directory. When the Servlet Container starts, it will preload your servlet in memory if specified in the web.xml configuration file. If your servlet is not already loaded (not listed in the web.xml configuration file), its instance will be created as soon as a request for it is received by the Servlet Container. The first time it is loaded, the container calls your servlet's init() method, if there is one. Notice that it gets called only once, so place one-off functionality in this method (such as database connection, file object). Now that your servlet is ready, it waits for requests. The container will call your service() method each time a request is received for your servlet. The HttpServlet class (which your servlet must extend) already has this method, so you don't have to write one, but you can override it. The service() method then passes the request on to the appropriate method (usually GET for simple requests and POST to submit data, say a Web page form) such as the doGet() method if it is a GET request, or the doPost() method if it is a POST request. The doXXX() methods are the ones you need to override and where you will spend most of your effort. The servlet processes the request (code you write in doGet()), returning a response to the container. The container sends the text of the response back to the browser.
The preceding JSP and servlet examples are part of a Web application. A Web application is a collection of servlets, JSP pages, HTML documents, and other Web resources (such as image files, compressed archives, and other data). This collection may be packaged into an archive or exist as separate files in an open directory structure. Since you have many servlet classes, JSP pages, HTML pages, and other supporting libraries and files for a given Web application, there are many dependencies. These are not trivial to manage. It is vital that all parts go in their correct locations in the Web application archive or in an open directory structure. Once you get the dependencies resolved, it is a good idea to package the collection into a Web application archive, a single file with the .war extension that contains all of the components of a Web application. You can do this using standard JAR tools.
Now, we need to define what is meant regarding deploying a Web application. Normally, Web applications run on only one VM at any one time. When we talk about deploying a Web application, we mean that the collection of files that comprise a Web application is placed into a Web server's runtime (at least one part goes into JVM, which can then link to or grab other parts). What happens if you want to deploy your Web application in a Web farm? In this case, your Web application will run on several VMs simultaneously.
A distributable Web application is written so that it can be deployed in a Web container, distributed across multiple Java virtual machines running on the same host or different hosts. The two keys to making this possible are how you thread the servlets and what you tell the deployment descriptor. With the right combination of these, your Web application will run on several VMs simultaneously. The servlet declaration, which is part of the deployment descriptor, controls how the Servlet Container provides instances of the servlet. Normally, the Servlet Container uses only one instance per servlet declaration. However, for a servlet implementing the SingleThreadModel interface, the Servlet Container may instantiate multiple instances to handle a heavy request load and serialize requests to a particular instance.
In the case where a servlet is marked in the deployment descriptor as distributable and the application implements the SingleThreadModel interface, the container may instantiate multiple instances of that servlet in each VM of the container or across many machines (clustering servlets usually through serialization). The container has a complicated task in managing requests, sessions, and contexts across JVMs. How each vendor accomplishes this is beyond the scope of this book. You do need to know that to convert your Web application into a distributable one, you must implement the SingleThreadModel interface and mark the servlet as distributable in the deployment descriptor (see Chapter 10, "Web Applications," for more about web.xml).