Java Servlets Tutorial

Java Servlets Tutorial

Last updated on 12th Oct 2020, Blog, Tutorials

About author

Arun ( (Sr Project Manager ) )

High level Domain Expert in TOP MNCs with 8+ Years of Experience. Also, Handled Around 20+ Projects and Shared his Knowledge by Writing these Blogs for us.

(5.0) | 12547 Ratings 2258

What Is a Servlet?

A servlet is a Java programming language class that is used to extend the capabilities of servers that host applications accessed by means of a request-response programming model. Although servlets can respond to any type of request, they are commonly used to extend the applications hosted by web servers. For such applications, Java Servlet technology defines HTTP-specific servlet classes.

The javax.servlet and javax.servlet.http packages provide interfaces and classes for writing servlets. All servlets must implement the Servlet interface, which defines life-cycle methods. When implementing a generic service, you can use or extend the GenericServlet class provided with the Java Servlet API. The HttpServlet class provides methods, such as doGet and doPost, for handling HTTP-specific services.

This chapter focuses on writing servlets that generate responses to HTTP requests.

Subscribe For Free Demo

Error: Contact form not found.

The Example Servlets

This chapter uses the Duke’s Bookstore application to illustrate the tasks involved in programming servlets. The source code for the bookstore application is located in the tut-install/javaeetutorial5/examples/web/bookstore1/ directory, which is created when you unzip the tutorial bundle (see Building the Examples).

Table 4-1 lists the servlets that handle each bookstore function. You can find these servlet classes in tut-install/javaeetutorial5/examples/web/bookstore1/src/java/com/sun/bookstore1/. Each programming task is illustrated by one or more servlets. For example, BookDetailsServlet illustrates how to handle HTTP GET requests, BookDetailsServlet and CatalogServlet show how to construct responses, and CatalogServlet illustrates how to track session information.

Table 4-1 Duke’s Bookstore Example Servlets

FunctionServlet
Enter the bookstoreBookStoreServlet
Create the bookstore bannerBannerServlet
Browse the bookstore catalogCatalogServlet
Put a book in a shopping cartCatalogServlet,BookDetailsServlet
Get detailed information on a specific bookBookDetailsServlet
Display the shopping cartShowCartServlet
Remove one or more books from the shopping cartShowCartServlet
Buy the books in the shopping cartCashierServlet
Send an acknowledgment of the purchaseReceiptServlet

The data for the bookstore application is maintained in a database and accessed through the database access class database.BookDBAO. The database package also contains the class Book which represents a book. The shopping cart and shopping cart items are represented by the classes cart.ShoppingCart and cart.ShoppingCartItem, respectively.

To deploy and run the application using NetBeans IDE, follow these steps:

  • Perform all the operations described in Accessing Databases from Web Applications.
  • In NetBeans IDE, select File→Open Project.
  • In the Open Project dialog, navigate to:
    tut-install/javaeetutorial5/examples/web/
  • Select the bookstore1 folder.
  • Select the Open as Main Project checkbox and the Open Required Projects check box.
  • Click Open Project.
  • In the Projects tab, right-click the bookstore1 project, and select Undeploy and Deploy.
  • To run the application, open the bookstore URL http://localhost:8080/bookstore1/bookstore.

To deploy and run the application using Ant, follow these steps:

  • In a terminal window, go to tut-install/javaeetutorial5/examples/web/bookstore1/.
  • Type ant. This command will spawn any necessary compilations, copy files to the tut-install/javaeetutorial5/examples/web/bookstore1/build/ directory, and create a WAR file and copy it to the tut-install/javaeetutorial5/examples/web/bookstore1/dist/ directory.
  • Start the Application Server.
  • Perform all the operations described in Creating a Data Source in the Application Server.
  • To deploy the example, type ant deploy. The deploy target outputs a URL for running the application. Ignore this URL, and instead use the one shown in the next step.
  • To run the application, open the bookstore URL http://localhost:8080/bookstore1/bookstore.

To learn how to configure the example, refer to the deployment descriptor (the web.xml file), which includes the following configurations:

  • A display-name element that specifies the name that tools use to identify the application.
  • A set of filter elements that identify servlet filters contained in the application.
  • A set of filter-mapping elements that identify which servlets will have their requests or responses filtered by the filters identified by the filter elements. A filter-mapping element can define more than one servlet mapping and more than one URL pattern for a particular filter.
  • A set of servlet elements that identify all the servlet instances of the application.
  • A set of servlet-mapping elements that map the servlets to URL patterns. More than one URL pattern can be defined for a particular servlet.
  • A set of error-page mappings that map exception types to an HTML page, so that the HTML page opens when an exception of that type is thrown by the application.

Troubleshooting Duke’s Bookstore Database Problems

The Duke’s Bookstore database access object returns the following exceptions:

  • BookNotFoundException: Returned if a book can’t be located in the bookstore database. This will occur if you haven’t loaded the bookstore database with data or the server has not been started or has crashed. You can populate the database by running ant create-tables.
  • BooksNotFoundException: Returned if the bookstore data can’t be retrieved. This will occur if you haven’t loaded the bookstore database with data or if the database server hasn’t been started or it has crashed.
  • UnavailableException: Returned if a servlet can’t retrieve the web context attribute representing the bookstore. This will occur if the database server hasn’t been started.

Because you have specified an error page, you will see the message

The application is unavailable. Please try later.

If you don’t specify an error page, the web container generates a default page containing the message

A Servlet Exception Has Occurred

and a stack trace that can help you diagnose the cause of the exception. If you use errorpage.html, you will have to look in the server log to determine the cause of the exception.

Servlet Life Cycle

The life cycle of a servlet is controlled by the container in which the servlet has been deployed. When a request is mapped to a servlet, the container performs the following steps.

  • If an instance of the servlet does not exist, the web container
    • Loads the servlet class.
    • Creates an instance of the servlet class.
    • Initializes the servlet instance by calling the init method. Initialization is covered in Initializing a Servlet.
  • Invokes the service method, passing request and response objects. Service methods are discussed in Writing Service Methods.

If the container needs to remove the servlet, it finalizes the servlet by calling the servlet’s destroy method. Finalization is discussed in Finalizing a Servlet.

Handling Servlet Life-Cycle Events

You can monitor and react to events in a servlet’s life cycle by defining listener objects whose methods get invoked when life-cycle events occur. To use these listener objects you must define and specify the listener class.

Defining the Listener Class

You define a listener class as an implementation of a listener interface. Table 4-2 lists the events that can be monitored and the corresponding interface that must be implemented. When a listener method is invoked, it is passed an event that contains information appropriate to the event. For example, the methods in the HttpSessionListener interface are passed an HttpSessionEvent, which contains an HttpSession.

Table 4-2 Servlet Life-Cycle Events

ObjectEventListener Interface and Event Class
Web context (see Accessing the Web Context)Initialization and destructionjavax.servlet.ServletContextListener andServletContextEvent
Attribute added, removed, or replacedjavax.servlet.ServletContextAttributeListener andServletContextAttributeEvent
Session (See Maintaining Client State)Creation, invalidation, activation, passivation, and timeoutjavax.servlet.http.HttpSessionListener, javax.servlet.http.HttpSessionActivationListener, andHttpSessionEvent
Attribute added, removed, or replacedjavax.servlet.http.HttpSessionAttributeListener andHttpSessionBindingEvent
RequestA servlet request has started being processed by web componentsjavax.servlet.ServletRequestListener andServletRequestEvent
Attribute added, removed, or replacedjavax.servlet.ServletRequestAttributeListener andServletRequestAttributeEvent

The tut-

install/javaeetutorial5/examples/web/bookstore1/src/java/com/sun/bookstore1/listeners/ContextListener class creates and removes the database access and counter objects used in the Duke’s Bookstore application. The methods retrieve the web context object from ServletContextEvent and then store (and remove) the objects as servlet context attributes.

  • import database.BookDBAO;
  • import javax.servlet.*;
  • import util.Counter;
  • import javax.ejb.*;
  • import javax.persistence.*;
  • public final class ContextListener
  •     implements ServletContextListener {
  •     private ServletContext context = null;
  •     @PersistenceUnit
  •     EntityManagerFactory emf;
  •     public void contextInitialized(ServletContextEvent event) {
  •         context = event.getServletContext();
  •         try {
  •             BookDBAO bookDB = new BookDBAO(emf);
  •             context.setAttribute(“bookDB”, bookDB);
  •         } catch (Exception ex) {
  •             System.out.println(
  •                 “Couldn’t create database: ” + ex.getMessage());
  •         }
  •         Counter counter = new Counter();
  •         context.setAttribute(“hitCounter”, counter);
  •         counter = new Counter();
  •         context.setAttribute(“orderCounter”, counter);
  •     }
  •         context = event.getServletContext();
  •         BookDBAO bookDB = context.getAttribute(“bookDB”);
  •         bookDB.remove();
  •         context.removeAttribute(“bookDB”);
  •         context.removeAttribute(“hitCounter”);
  •         context.removeAttribute(“orderCounter”);
  •     }
  • }

Specifying Event Listener Classes

You specify an event listener class using the listener element of the deployment descriptor. Review The Example Servlets for information on how to specify the ContextListener listener class.

You can specify an event listener using the deployment descriptor editor of NetBeans IDE by doing the following:

  • Expand your application’s project node.
  • Expand the project’s Web Pages and WEB-INF nodes.
  • Double-click web.xml.
  • Click General at the top of the web.xml editor.
  • Expand the Web Application Listeners node.
  • Click Add.
  • In the Add Listener dialog, click Browse to locate the listener class.
  • Click OK.

Handling Servlet Errors

Any number of exceptions can occur when a servlet executes. When an exception occurs, the web container generates a default page containing the message

A Servlet Exception Has Occurred

But you can also specify that the container should return a specific error page for a given exception. Review the deployment descriptor file included with the example to learn how to map the exceptions exception.BookNotFound, exception.BooksNotFound, and exception.OrderException returned by the Duke’s Bookstore application to errorpage.html.

See Mapping Errors to Error Screens for instructions on how to specify error pages using NetBeans IDE.

Sharing Information

Web components, like most objects, usually work with other objects to accomplish their tasks. There are several ways they can do this. They can use private helper objects (for example, JavaBeans components), they can share objects that are attributes of a public scope, they can use a database, and they can invoke other web resources. The Java Servlet technology mechanisms that allow a web component to invoke other web resources are described in Invoking Other Web Resources.

Using Scope Objects

Collaborating web components share information by means of objects that are maintained as attributes of four scope objects. You access these attributes using the [get|set]Attribute methods of the class representing the scope. Table 4-3 lists the scope objects.

Table 4-3 Scope Objects

Scope ObjectClassAccessible From
Web contextjavax.servlet.ServletContextWeb components within a web context. See Accessing the Web Context.
Sessionjavax.servlet.http.HttpSessionWeb components handling a request that belongs to the session. See Maintaining Client State.
RequestSubtype of javax.servlet.ServletRequestWeb components handling the request.
Pagejavax.servlet.jsp.JspContextThe JSP page that creates the object. See Using Implicit Objects.

Figure 4-1 shows the scoped attributes maintained by the Duke’s Bookstore application.

Figure 4-1 Duke’s Bookstore Scoped Attributes

web-scopedAttributes

Controlling Concurrent Access to Shared Resources

In a multithreaded server, it is possible for shared resources to be accessed concurrently. In addition to scope object attributes, shared resources include in-memory data (such as instance or class variables) and external objects such as files, database connections, and network connections.

Concurrent access can arise in several situations:

  • Multiple web components accessing objects stored in the web context.
  • Multiple web components accessing objects stored in a session.
  • Multiple threads within a web component accessing instance variables. A web container will typically create a thread to handle each request. If you want to ensure that a servlet instance handles only one request at a time, a servlet can implement the SingleThreadModel interface. If a servlet implements this interface, you are guaranteed that no two threads will execute concurrently in the servlet’s service method. A web container can implement this guarantee by synchronizing access to a single instance of the servlet, or by maintaining a pool of web component instances and dispatching each new request to a free instance. This interface does not prevent synchronization problems that result from web components accessing shared resources such as static class variables or external objects. In addition, the Servlet 2.4 specification deprecates the SingleThreadModel interface.

When resources can be accessed concurrently, they can be used in an inconsistent fashion. To prevent this, you must control the access using the synchronization techniques described in the Threads lesson in The Java Tutorial, Fourth Edition, by Sharon Zakhour et al. (Addison-Wesley, 2006).

The preceding section showed five scoped attributes shared by more than one servlet: bookDB, cart, currency, hitCounter, and orderCounter. The bookDB attribute is discussed in the next section. The cart, currency, and counters can be set and read by multiple multithreaded servlets. To prevent these objects from being used inconsistently, access is controlled by synchronized methods. For example, here is the Counter class, located at tut-install/javaeetutorial5/examples/web/bookstore1/src/java/com/sun/bookstore1/util/:

  • public class Counter {
  •     private int counter;
  •     public Counter() {
  •         counter = 0;
  •     }
  •     public synchronized int getCounter() {
  •         return counter;
  •     }
  •     public synchronized int setCounter(int c) {
  •         counter = c;
  •         return counter;
  •     }
  •     public synchronized int incCounter() {
  •         return(++counter);
  •     }
  • }
Course Curriculum

Get Best Java Servlets Training with In-Depth Course Modules By Expert Trainers

  • Instructor-led Sessions
  • Real-life Case Studies
  • Assignments
Explore Curriculum

Accessing Databases

Data that is shared between web components and is persistent between invocations of a web application is usually maintained by a database. Web components use the Java Persistence API to access relational databases. The data for Duke’s Bookstore is maintained in a database and is accessed through the database access class tut-install/javaeetutorial5/examples/web/bookstore1/src/java/com/sun/bookstore1/database/BookDBAO. For example, ReceiptServlet invokes the BookDBAO.buyBooks method to update the book inventory when a user makes a purchase. The buyBooks method invokes buyBook for each book contained in the shopping cart, as shown in the following code.

  • public void buyBooks(ShoppingCart cart) throws OrderException{
  •     Collection items = cart.getItems();
  •     Iterator i = items.iterator();
  •     try {
  •         while (i.hasNext()) {
  •             ShoppingCartItem sci = (ShoppingCartItem)i.next();
  •             Book bd = (Book)sci.getItem();
  •             String id = bd.getBookId();
  •             int quantity = sci.getQuantity();
  •             buyBook(id, quantity);
  •         }
  •     } catch (Exception ex) {
  •         throw new OrderException(“Commit failed: ” +
  •             ex.getMessage());
  •      }
  • }
  • public void buyBook(String bookId, int quantity)
  •      throws OrderException {
  •     try {
  •         Book requestedBook = em.find(Book.class, bookId);
  •         if (requestedBook != null) {
  •             int inventory = requestedBook.getInventory();
  •             if ((inventory – quantity) >= 0) {
  •                 int newInventory = inventory – quantity;
  •                 requestedBook.setInventory(newInventory);
  •             } else{
  •                 throw new OrderException(“Not enough of “
  •                      + bookId + ” in stock to complete order.”);
  •             }
  •         }
  •     } catch (Exception ex) {
  •         throw new OrderException(“Couldn’t purchase book: “
  •              + bookId + ex.getMessage());
  •     }
  • }

To ensure that the order is processed in its entirety, the call to buyBooks is wrapped in a single transaction. In the following code, the calls to the begin and commit methods of UserTransaction mark the boundaries of the transaction. The call to the rollback method of UserTransaction undoes the effects of all statements in the transaction so as to protect the integrity of the data.

  • try {
  •     utx.begin();
  •     bookDB.buyBooks(cart);
  •     utx.commit();
  • } catch (Exception ex) {
  •     try {
  •         utx.rollback();
  •     } catch(Exception e) {
  •         System.out.println(“Rollback failed: “+e.getMessage());
  •     }
  •     System.err.println(ex.getMessage());
  •     orderCompleted = false;}
  • }

Initializing a Servlet

After the web container loads and instantiates the servlet class and before it delivers requests from clients, the web container initializes the servlet. To customize this process to allow the servlet to read persistent configuration data, initialize resources, and perform any other one-time activities, you override the init method of the Servlet interface. A servlet that cannot complete its initialization process should throw UnavailableException.

All the servlets that access the bookstore database (BookStoreServlet, CatalogServlet, BookDetailsServlet, and ShowCartServlet) initialize a variable in their init method that points to the database access object created by the web context listener:

  • public class CatalogServlet extends HttpServlet {
  •     private BookDBAO bookDB;
  •     public void init() throws ServletException {
  •         bookDB = (BookDBAO)getServletContext().
  •             getAttribute(“bookDB”);
  •         if (bookDB == null) throw new
  •             UnavailableException(“Couldn’t get database.”);
  •     }

What Is a Servlet?

A servlet is a Java programming language class that is used to extend the capabilities of servers that host applications accessed by means of a request-response programming model. Although servlets can respond to any type of request, they are commonly used to extend the applications hosted by web servers. For such applications, Java Servlet technology defines HTTP-specific servlet classes.

The javax.servlet and javax.servlet.http packages provide interfaces and classes for writing servlets. All servlets must implement the Servlet interface, which defines life-cycle methods. When implementing a generic service, you can use or extend the GenericServlet class provided with the Java Servlet API. The HttpServlet class provides methods, such as doGet and doPost, for handling HTTP-specific services.

This chapter focuses on writing servlets that generate responses to HTTP requests.

The Example Servlets

This chapter uses the Duke’s Bookstore application to illustrate the tasks involved in programming servlets. The source code for the bookstore application is located in the tut-install/javaeetutorial5/examples/web/bookstore1/ directory, which is created when you unzip the tutorial bundle (see Building the Examples).

Table 4-1 lists the servlets that handle each bookstore function. You can find these servlet classes in tut-install/javaeetutorial5/examples/web/bookstore1/src/java/com/sun/bookstore1/. Each programming task is illustrated by one or more servlets. For example, BookDetailsServlet illustrates how to handle HTTP GET requests, BookDetailsServlet and CatalogServlet show how to construct responses, and CatalogServlet illustrates how to track session information.

Table 4-1 Duke’s Bookstore Example Servlets

FunctionServlet
Enter the bookstoreBookStoreServlet
Create the bookstore bannerBannerServlet
Browse the bookstore catalogCatalogServlet
Put a book in a shopping cartCatalogServlet,BookDetailsServlet
Get detailed information on a specific bookBookDetailsServlet
Display the shopping cartShowCartServlet
Remove one or more books from the shopping cartShowCartServlet
Buy the books in the shopping cartCashierServlet
Send an acknowledgment of the purchaseReceiptServlet

The data for the bookstore application is maintained in a database and accessed through the database access class database.BookDBAO. The database package also contains the class Book which represents a book. The shopping cart and shopping cart items are represented by the classes cart.ShoppingCart and cart.ShoppingCartItem, respectively.

To deploy and run the application using NetBeans IDE, follow these steps:

  • Perform all the operations described in Accessing Databases from Web Applications.
  • In NetBeans IDE, select File→Open Project.
  • In the Open Project dialog, navigate to:
    tut-install/javaeetutorial5/examples/web/
  • Select the bookstore1 folder.
  • Select the Open as Main Project checkbox and the Open Required Projects check box.
  • Click Open Project.
  • In the Projects tab, right-click the bookstore1 project, and select Undeploy and Deploy.
  • To run the application, open the bookstore URL http://localhost:8080/bookstore1/bookstore.

To deploy and run the application using Ant, follow these steps:

  • In a terminal window, go to tut-install/javaeetutorial5/examples/web/bookstore1/.
  • Type ant. This command will spawn any necessary compilations, copy files to the tut-install/javaeetutorial5/examples/web/bookstore1/build/ directory, and create a WAR file and copy it to the tut-install/javaeetutorial5/examples/web/bookstore1/dist/ directory.
  • Start the Application Server.
  • Perform all the operations described in Creating a Data Source in the Application Server.
  • To deploy the example, type ant deploy. The deploy target outputs a URL for running the application. Ignore this URL, and instead use the one shown in the next step.
  • To run the application, open the bookstore URL http://localhost:8080/bookstore1/bookstore.

To learn how to configure the example, refer to the deployment descriptor (the web.xml file), which includes the following configurations:

  • A display-name element that specifies the name that tools use to identify the application.
  • A set of filter elements that identify servlet filters contained in the application.
  • A set of filter-mapping elements that identify which servlets will have their requests or responses filtered by the filters identified by the filter elements. A filter-mapping element can define more than one servlet mapping and more than one URL pattern for a particular filter.
  • A set of servlet elements that identify all the servlet instances of the application.
  • A set of servlet-mapping elements that map the servlets to URL patterns. More than one URL pattern can be defined for a particular servlet.
  • A set of error-page mappings that map exception types to an HTML page, so that the HTML page opens when an exception of that type is thrown by the application.

Troubleshooting Duke’s Bookstore Database Problems

The Duke’s Bookstore database access object returns the following exceptions:

  • BookNotFoundException: Returned if a book can’t be located in the bookstore database. This will occur if you haven’t loaded the bookstore database with data or the server has not been started or has crashed. You can populate the database by running ant create-tables.
  • BooksNotFoundException: Returned if the bookstore data can’t be retrieved. This will occur if you haven’t loaded the bookstore database with data or if the database server hasn’t been started or it has crashed.
  • UnavailableException: Returned if a servlet can’t retrieve the web context attribute representing the bookstore. This will occur if the database server hasn’t been started.

Because you have specified an error page, you will see the message

The application is unavailable. Please try later.

If you don’t specify an error page, the web container generates a default page containing the message

A Servlet Exception Has Occurred

and a stack trace that can help you diagnose the cause of the exception. If you use errorpage.html, you will have to look in the server log to determine the cause of the exception.

Servlet Life Cycle

The life cycle of a servlet is controlled by the container in which the servlet has been deployed. When a request is mapped to a servlet, the container performs the following steps.

  • If an instance of the servlet does not exist, the web container
    • Loads the servlet class.
    • Creates an instance of the servlet class.
    • Initializes the servlet instance by calling the init method. Initialization is covered in Initializing a Servlet.
  • Invokes the service method, passing request and response objects. Service methods are discussed in Writing Service Methods.

If the container needs to remove the servlet, it finalizes the servlet by calling the servlet’s destroy method. Finalization is discussed in Finalizing a Servlet.

Handling Servlet Life-Cycle Events

You can monitor and react to events in a servlet’s life cycle by defining listener objects whose methods get invoked when life-cycle events occur. To use these listener objects you must define and specify the listener class.

Defining the Listener Class

You define a listener class as an implementation of a listener interface. Table 4-2 lists the events that can be monitored and the corresponding interface that must be implemented. When a listener method is invoked, it is passed an event that contains information appropriate to the event. For example, the methods in the HttpSessionListener interface are passed an HttpSessionEvent, which contains an HttpSession.

Table 4-2 Servlet Life-Cycle Events

ObjectEventListener Interface and Event Class
Web context (see Accessing the Web Context)Initialization and destructionjavax.servlet.ServletContextListener andServletContextEvent
Attribute added, removed, or replacedjavax.servlet.ServletContextAttributeListener andServletContextAttributeEvent
Session (See Maintaining Client State)Creation, invalidation, activation, passivation, and timeoutjavax.servlet.http.HttpSessionListener, javax.servlet.http.HttpSessionActivationListener, andHttpSessionEvent
Attribute added, removed, or replacedjavax.servlet.http.HttpSessionAttributeListener andHttpSessionBindingEvent
RequestA servlet request has started being processed by web componentsjavax.servlet.ServletRequestListener andServletRequestEvent
Attribute added, removed, or replacedjavax.servlet.ServletRequestAttributeListener andServletRequestAttributeEvent

The tut-install/javaeetutorial5/examples/web/bookstore1/src/java/com/sun/bookstore1/listeners/ContextListener class creates and removes the database access and counter objects used in the Duke’s Bookstore application. The methods retrieve the web context object from ServletContextEvent and then store (and remove) the objects as servlet context attributes.

  • import database.BookDBAO;
  • import javax.servlet.*;
  • import util.Counter;
  • import javax.ejb.*;
  • import javax.persistence.*;
  • public final class ContextListener
  •     implements ServletContextListener {
  •     private ServletContext context = null;
  •     @PersistenceUnit
  •     EntityManagerFactory emf;
  •     public void contextInitialized(ServletContextEvent event) {
  •         context = event.getServletContext();
  •         try {
  •             BookDBAO bookDB = new BookDBAO(emf);
  •             context.setAttribute(“bookDB”, bookDB);
  •         } catch (Exception ex) {
  •             System.out.println(
  •                 “Couldn’t create database: ” + ex.getMessage());
  •         }
  •         Counter counter = new Counter();
  •         context.setAttribute(“hitCounter”, counter);
  •         counter = new Counter();
  •         context.setAttribute(“orderCounter”, counter);
  •     }
  •     public void contextDestroyed(ServletContextEvent event) {
  •         context = event.getServletContext();
  •         BookDBAO bookDB = context.getAttribute(“bookDB”);
  •         bookDB.remove();
  •         context.removeAttribute(“bookDB”);
  •         context.removeAttribute(“hitCounter”);
  •         context.removeAttribute(“orderCounter”);
  •     }
  • }

Specifying Event Listener Classes

You specify an event listener class using the listener element of the deployment descriptor. Review The Example Servlets for information on how to specify the ContextListener listener class.

You can specify an event listener using the deployment descriptor editor of NetBeans IDE by doing the following:

  • Expand your application’s project node.
  • Expand the project’s Web Pages and WEB-INF nodes.
  • Double-click web.xml.
  • Click General at the top of the web.xml editor.
  • Expand the Web Application Listeners node.
  • Click Add.
  • In the Add Listener dialog, click Browse to locate the listener class.
  • Click OK.

Handling Servlet Errors

Any number of exceptions can occur when a servlet executes. When an exception occurs, the web container generates a default page containing the message

A Servlet Exception Has Occurred

But you can also specify that the container should return a specific error page for a given exception. Review the deployment descriptor file included with the example to learn how to map the exceptions exception.BookNotFound, exception.BooksNotFound, and exception.OrderException returned by the Duke’s Bookstore application to errorpage.html.

See Mapping Errors to Error Screens for instructions on how to specify error pages using NetBeans IDE.

Sharing Information

Web components, like most objects, usually work with other objects to accomplish their tasks. There are several ways they can do this. They can use private helper objects (for example, JavaBeans components), they can share objects that are attributes of a public scope, they can use a database, and they can invoke other web resources. The Java Servlet technology mechanisms that allow a web component to invoke other web resources are described in Invoking Other Web Resources.

Using Scope Objects

Collaborating web components share information by means of objects that are maintained as attributes of four scope objects. You access these attributes using the [get|set]Attribute methods of the class representing the scope. Table 4-3 lists the scope objects.

Table 4-3 Scope Objects

Scope ObjectClassAccessible From
Web contextjavax.servlet.ServletContextWeb components within a web context. See Accessing the Web Context.
Sessionjavax.servlet.http.HttpSessionWeb components handling a request that belongs to the session. See Maintaining Client State.
RequestSubtype of javax.servlet.ServletRequestWeb components handling the request.
Pagejavax.servlet.jsp.JspContextThe JSP page that creates the object. See Using Implicit Objects.

Figure 4-1 shows the scoped attributes maintained by the Duke’s Bookstore application.

Figure 4-1 Duke’s Bookstore Scoped Attributes

web-scopedAttributes -2
Java Sample Resumes! Download & Edit, Get Noticed by Top Employers! Download

Controlling Concurrent Access to Shared Resources

In a multithreaded server, it is possible for shared resources to be accessed concurrently. In addition to scope object attributes, shared resources include in-memory data (such as instance or class variables) and external objects such as files, database connections, and network connections.

Concurrent access can arise in several situations:

  • Multiple web components accessing objects stored in the web context.
  • Multiple web components accessing objects stored in a session.
  • Multiple threads within a web component accessing instance variables. A web container will typically create a thread to handle each request. If you want to ensure that a servlet instance handles only one request at a time, a servlet can implement the SingleThreadModel interface. If a servlet implements this interface, you are guaranteed that no two threads will execute concurrently in the servlet’s service method. A web container can implement this guarantee by synchronizing access to a single instance of the servlet, or by maintaining a pool of web component instances and dispatching each new request to a free instance. This interface does not prevent synchronization problems that result from web components accessing shared resources such as static class variables or external objects. In addition, the Servlet 2.4 specification deprecates the SingleThreadModel interface.

When resources can be accessed concurrently, they can be used in an inconsistent fashion. To prevent this, you must control the access using the synchronization techniques described in the Threads lesson in The Java Tutorial, Fourth Edition, by Sharon Zakhour et al. (Addison-Wesley, 2006).

The preceding section showed five scoped attributes shared by more than one servlet: bookDB, cart, currency, hitCounter, and orderCounter. The bookDB attribute is discussed in the next section. The cart, currency, and counters can be set and read by multiple multithreaded servlets. To prevent these objects from being used inconsistently, access is controlled by synchronized methods. For example, here is the Counter class, located at tutinstall/javaeetutorial5/examples/web/bookstore1/src/java/com/sun/bookstore1/util/:

  • public class Counter {
  •     private int counter;
  •     public Counter() {
  •         counter = 0;
  •     }
  •     public synchronized int getCounter() {
  •         return counter;
  •     }
  •     public synchronized int setCounter(int c) {
  •         counter = c;
  •         return counter;
  •     }
  •     public synchronized int incCounter() {
  •         return(++counter);
  •     }
  • }

Accessing Databases

Data that is shared between web components and is persistent between invocations of a web application is usually maintained by a database. Web components use the Java Persistence API to access relational databases. The data for Duke’s Bookstore is maintained in a database and is accessed through the database access class tut-install/javaeetutorial5/examples/web/bookstore1/src/java/com/sun/bookstore1/database/BookDBAO. For example, ReceiptServlet invokes the BookDBAO.buyBooks method to update the book inventory when a user makes a purchase. The buyBooks method invokes buyBook for each book contained in the shopping cart, as shown in the following code.

  • public void buyBooks(ShoppingCart cart) throws OrderException{
  •     Collection items = cart.getItems();
  •     Iterator i = items.iterator();
  •     try {
  •         while (i.hasNext()) {
  •             ShoppingCartItem sci = (ShoppingCartItem)i.next();
  •             Book bd = (Book)sci.getItem();
  •             String id = bd.getBookId();
  •             int quantity = sci.getQuantity();
  •             buyBook(id, quantity);
  •         }
  •     } catch (Exception ex) {
  •         throw new OrderException(“Commit failed: ” +
  •             ex.getMessage());
  •      }
  • }
  • public void buyBook(String bookId, int quantity)
  •      throws OrderException {
  •     try {
  •         Book requestedBook = em.find(Book.class, bookId);
  •         if (requestedBook != null) {
  •             int inventory = requestedBook.getInventory();
  •             if ((inventory – quantity) >= 0) {
  •                 int newInventory = inventory – quantity;
  •                 requestedBook.setInventory(newInventory);
  •             } else{
  •                 throw new OrderException(“Not enough of “
  •                      + bookId + ” in stock to complete order.”);
  •             }
  •         }
  •     } catch (Exception ex) {
  •         throw new OrderException(“Couldn’t purchase book: “
  •              + bookId + ex.getMessage());
  •     }
  • }

To ensure that the order is processed in its entirety, the call to buyBooks is wrapped in a single transaction. In the following code, the calls to the begin and commit methods of UserTransaction mark the boundaries of the transaction. The call to the rollback method of UserTransaction undoes the effects of all statements in the transaction so as to protect the integrity of the data.

  • try {
  •     utx.begin();
  •     bookDB.buyBooks(cart);
  •     utx.commit();
  • } catch (Exception ex) {
  •     try {
  •         utx.rollback();
  •     } catch(Exception e) {
  •         System.out.println(“Rollback failed: “+e.getMessage());
  •     }
  •     System.err.println(ex.getMessage());
  •     orderCompleted = false;}
  • }

Initializing a Servlet

After the web container loads and instantiates the servlet class and before it delivers requests from clients, the web container initializes the servlet. To customize this process to allow the servlet to read persistent configuration data, initialize resources, and perform any other one-time activities, you override the init method of the Servlet interface. A servlet that cannot complete its initialization process should throw UnavailableException.

All the servlets that access the bookstore database (BookStoreServlet, CatalogServlet, BookDetailsServlet, and ShowCartServlet) initialize a variable in their init method that points to the database access object created by the web context listener:

  • public class CatalogServlet extends HttpServlet {
  •     private BookDBAO bookDB;
  •     public void init() throws ServletException {
  •         bookDB = (BookDBAO)getServletContext().
  •             getAttribute(“bookDB”);
  •         if (bookDB == null) throw new
  •             UnavailableException(“Couldn’t get database.”);
  •     }
  • }
  • }

Are you looking training with Right Jobs?

Contact Us

Popular Courses