Home Javacertification Ibm-287 Chapter 2. Design, build and test web components

Ask Questions?

View Latest Questions

Advertisement


 
 

Chapter 2. Design, build and test web components
Posted on: May 4, 2011 at 12:00 AM
Chapter 2. Design, build and test web components

		message = qSession.createMapMessage();
		message.setString("name", firstName + " " + lastName);
		message.setString("cruise", cruise);
		qSender.send(message);
		qConn.close();
		System.out.println("TravelAgentBean: Cruise reservation sent");
	} catch (Exception e) {
		System.err.println("TravelAgentBean: Error on sending message " + e);
	}
}
					

Servlet filters

Servlet filters are pluggable Web components that allow us to implement pre-processing and post-processing logic in our Web applications. Filters support the basic request processing facilities of servlets and JSP pages, such as:

  • Authentication

  • Logging and auditing

  • Image conversion

  • Data compression

  • Encryption

  • Tokenizing

  • Trigger resource access events

  • XSL/T filters that transform XML content

  • MIME-type chain

  • Caching

Servlet filters are small Web components that intercept requests and responses to view, extract, or in some way manipulate the data that is being exchanged between client and server. Filters are Web components that typically encapsulate some functionality that, while important, is not central to processing the client request or sending a response. Typical examples include logging data about the request or response, processing security protocols, managing session attributes, and more. Filters provide a modular, object-oriented mechanism for encapsulating common tasks into pluggable components that are declared via a configuration file and processed dynamically.

Many elements combine in Servlet filters to make them unique, powerful, and modular Web components. Namely, Servlet filters are:

  • Declarative: Filters are declared via XML tags in the Web deployment descriptor (web.xml). This allows filters to be added and removed without touching any application code or JSP pages.

  • Dynamic: At runtime, filters are invoked by the Servlet container to intercept and process requests and responses.

  • Flexible: The application of filters to a Web processing environment is broad, covering many of the most common auxiliary's tasks such as logging and security. Filters are also flexible because they can be used to perform pre- and post-processing on calls directly from clients, as well as handling dispatched requests between Web components behind the firewall. Finally, filters can be chained together to provide required functionality.

  • Modular: By encapsulating application-processing logic into a single class file, filters define modular units that can be easily added to and removed from a request/response chain.

  • Portable: As with so many aspects of the Java platform, Servlet filters are portable across platforms and containers, further bolstering the modular and reusable qualities of Servlet filters.

  • Reusable: Thanks to the modular design of a filter's implementation class, and the declarative way that a filter is configured, filters can easily be used across projects and applications.

  • Transparent: The inclusion of a filter within a request/response chain is designed to supplement, but in no way replace, the core processing provided by a servlet or JSP page. Thus, filters can be added or removed as necessary without breaking the servlet or JSP page.

Servlet filters are modular, reusable components that are flexibly declared via a configuration file. Filters process incoming requests and outgoing responses dynamically and can be transparently added and removed without modifying application code. Finally, filters are independent of any platform or Servlet container, allowing them to be easily deployed in any compliant J2EE environment.

The Servlet filter architecture

The application developer creates a filter by implementing the javax.servlet.Filter interface and providing a public constructor taking no arguments. The class is packaged in the Web Archive along with the static content and servlets that make up the Web application. A filter is declared using the <filter> element in the deployment descriptor. A filter or collection of filters can be configured for invocation by defining <filter-mapping> elements in the deployment descriptor. This is done by mapping filters to a particular servlet by the servlet's logical name, or mapping to a group of servlets and static content resources by mapping a filter to a URL pattern.

As the name suggests, a Servlet filter is used to intercept an incoming request and/or outgoing response, and monitor, modify, or in some way process the stream of data that is passing through. Filters are self-contained, modular components that can be added to a request/response chain, or removed without affecting the other Web components in the application. Filters simply alter the runtime processing of requests and responses, and thus should not be tied directly into the Web application framework, except through well-defined standard interfaces within the Servlet API.

A Web resource can be configured to have no filters associated with it (default), a single filter (typical), or even a chain of filters. Like a servlet, a filter receives a request and response object. The filter will then inspect the request object and decide to forward the request to the next component in the chain, or stop the request and send a response directly back to the client. If the request is forwarded, it is passed to the next resource in the chain (another filter, a servlet, or a JSP page). After the request works its way through the chain and is processed by the server, a response is sent back through the chain in reverse order. This gives each filter an opportunity to handle the response object if necessary.

The order the container uses in building the chain of filters to be applied for a particular request URI is as follows:

  1. First, the <url-pattern> matching filter mappings in the same order that these elements appear in the deployment descriptor.

  2. Next, the <servlet-name> matching filter mappings in the same order that these elements appear in the deployment descriptor.

Creating a new filter class

The Filter wizard enables you to create Java filter classes for various J2EE filter types, such as authentication filters, encryption filters, and data compression filters.

To create a filter class, do the following:

  1. To launch the Filter wizard, from the Web perspective select File > New > Filter.

  2. On the Filter page, supply the following:

    • Specify the folder where the filter class will be placed, the package (com.titan.filters) that the class will belong to (it is added into a default package if you do not specify one) , and a name for the filter. The Class name value should be the class name of the filter (LoggingFilter).

      NOTE: You should place the filter in the Java source folder.

    • Specify a Superclass for the filter class. A filter created by this wizard can have any class that has Object in its hierarchy as its superclass. Click Browse to choose from the available superclasses.

    New filter
  3. Click Next.

  4. Select a modifier to specify whether your filter class is public, abstract, or final. (Classes cannot be both abstract and final.)

  5. The javax.servlet.Filter is provided as the default Interface. You do not have to implement the Filter interface if you subclass a class that implements Filter, or if you implement an interface which has Filter in its hierarchy.

    You can also add additional interfaces to implement. Click Add to open the Interface Selection dialog. In this dialog, as you type the name of the interface that you are interested in adding in the Choose interfaces field, the list of available interfaces listed in the Matching types list box updates dynamically to display only the interfaces that match the pattern. Choose an interface to see the Qualifier and click Add. Click OK when you are finished.

  6. Choose which method stub you want to create.

    The Inherited abstract methods option adds stubs for inherited abstract methods and that must be implemented (unless you intend to create an abstract class). Because the init(), destroy(), and doFilter() methods are all defined in the javax.servlet.Filter interface, stubs for these methods are automatically generated for each new filter class.

    New filter
  7. Click Next.

  8. Add deployment information to the Web project's web.xml file.

    If you select the Add to web.xml check box, the filter, along with its display name, and any initialization parameters, URL mappings, and servlet mappings added using this page will be automatically included in the Web project web.xml file.

    The Class name value provided in a previous page of the wizard is automatically mapped on this page as the Filter Name. The mapping is not updated if you change the value in the Filter Name field on this page.

    Any filter mappings specified will be inserted after existing filter mappings in the web.xml file. So, if you want the filter to be invoked before other filters for the same mapped resource, you should use the Web Deployment Descriptor editor to update the ordering. URL mappings take precedence over the servlet mappings.

    Filter mapping
  9. Click Finish.

    Filter

The filter that you requested is generated and added to the Java package that you designated under the Java source folder:

Implementing a Servlet filter

First, you program the filter implementation class, second add the filter to your Web application (by declaring it within the Web deployment descriptor - web.xml), and, finally, package the application with the filter and deploy it.

  1. Programming the implementation class

    The filter API consists of three simple interfaces within the javax.servlet package. Those three interfaces are Filter, FilterChain, and FilterConfig. From a programming standpoint, your filter class will implement the Filter interface and then use the FilterChain and FilterConfig interfaces within your filter class. Your filter class will be passed a reference to a FilterChain object to allow the filter to pass control to the next resource in the chain. The FilterConfig object will be supplied to the filter by the container to provide access to initialization data for the filter.

    A filter must apply three methods in order to fully implement the Filter interface:

    • init(..) : This method is called when the filter is instantiated by the container and is designed to prepare the filter for processing. The method accepts as input an object of type FilterConfig.

    • doFilter(...) : In the same way that servlets have a service(...) method (which in turn calls doPost(...) or doGet(...)) to handle requests, filters have a single method for processing requests and responses - doFilter(). This method accepts three input parameters: a ServletRequest, a ServletResponse, and a FilterChain object.

    • destroy(): This method performs any cleanup operations on the class that may need to take place prior to automatic garbage collection.

    Add the following code to the com.titan.filters.LoggingFilter filter class:

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
    	Date startTime = new Date();
    	
    	// Forward the request to the next resource in the chain
    	chain.doFilter(req, resp);
    	
    	// Calculate the difference between the start time and end time
    	Date endTime = new Date();
    	double totalTime = endTime.getTime() - startTime.getTime();
    	totalTime = totalTime / 1000; //Convert from milliseconds to seconds
    	
    	// Prepare log message
    	StringBuffer message = new StringBuffer("LoggingFilter: request to : ");
    	message.append(((HttpServletRequest) req).getServletPath());
    	message.append(" took ");
    	message.append(totalTime);
    	message.append(" seconds");
    	System.out.println(message.toString());
    }
    								
  2. Configuring the Servlet filter

    Filters are declared via two XML tags within the web.xml file.

    The <filter> tag defines a name for the filter and declares the implementation class and init(...) parameters. The <filter-mapping> tag associates a filter with a servlet or URL pattern.

    
    <filter>
    	<filter-name>LoggingFilter</filter-name>
    	<display-name>LoggingFilter</display-name>
    	<filter-class>com.titan.filters.LoggingFilter</filter-class>
    </filter>
    <filter-mapping>
    	<filter-name>LoggingFilter</filter-name>
    	<url-pattern>/*</url-pattern>
    </filter-mapping>
    								
    								

    In the above code sample, a filter ("LoggingFilter") is declared and mapped to an URL pattern ("/*") so that every request (indicated by the wildcard) should be sent to that filter.

  3. Deploying a Servlet filter

    Include the filter classes alongside your other Web component classes and place the web.xml - complete with filter definitions and filter mapping declarations - within the Web app structure as you would normally (at the root of the WEB-INF folder), and the servlet container will handle everything from there.

When you test your web application, the filter will track the approximate length of time taken to fulfill a client's Web request:

[17.08.05 16:26:46:656 EEST]  49a565a SystemOut     O LoggingFilter: request to : /ReservationController took 0.109 seconds					
					

The many uses of filters

Anywhere that a decorating filter pattern or interceptor pattern would be appropriate, you can use a filter. Some of the most common uses for filters are as follows:

  • Logging: The filter gleans information such as browser type, time of day, forwarding URL, etc. about all requests coming through the system and logs them.

  • Performance: The filter decompresses content as it comes across the wire before it hits the servlets and JSP pages, and then takes the response content and converts it into a compressed format before sending it on to the client machine.

  • Security: The filter handles management of authentication tokens and properly restricts access to secure resources, prompting the user for authentication and/or passing them off to a third party for authentication. A filter could even manage an Access Control List to provide authorization in addition to authentication. Placing security logic into a filter rather than a servlet or JSP page provides tremendous flexibility. During development, the filter can be turned off (comment out of web.xml). In production, the filter is turned back on. Also, multiple filters can be added to provide increasing levels of security, encryption, and non-repudiation services as necessary.

  • Session-handling: Littering your servlets and JSP pages with session-handling code can add up to quite a hassle. Using a filter to manage your session data lets your Web pages focus on displaying content and delegating processing, without worrying about the details of session management.

  • XSLT transformation: Whether you are working with a mobile client or an XML-based Web service, the ability to translate between XML grammars without embedding the logic into your application is absolutely priceless.

Fitting filters into an MVC architecture

The Model-View-Controller (MVC) architecture is an effective design that has now been incorporated as the overriding design methodology within the most popular Web application frameworks. Filters serve to augment the request/response processing flow of an MVC architecture. Whether the request/response is between the client and server or between other components on the server, the application of filters in the process flow is the same. From an MVC perspective, the dispatcher component (which is either included in or works in conjunction with the Controller component) forwards requests to the appropriate application component for processing. This makes the Controller layer the optimum location for including Servlet filters. Filters can be applied to all requests by placing them in front of the Controller component itself, or applied to individual Web components by placing it between the controller/dispatcher and the Model and View components.

Servlet Life-cycle Listener

The Java Servlet 2.3 specification provides mechanisms for notifying application code about events in the Web application life cycle. Life cycle events include creation and destruction of a servlet context or an HTTP session, and creation, modification, or removal of servlet context attributes and HTTP session attributes. Furthermore, any object may be notified when it is bound to or unbound from an HTTP session attribute.

Application life cycle listeners are often used to provide consistent, managed access to other resources. For example, consider a set of servlets within the same Web application that share a database connection on a single server. To improve performance, some servlets save a database connection as a servlet context attribute, and reuse it across multiple servlet service invocations for multiple clients. When the application is shut down, the database connection should be closed. To manage the database connection, an application developer creates a servlet context event listener. The listener class opens the database and initializes a context attribute with a reference when the application is deployed. The listener class also closes the database when the application is undeployed.

To create a life cycle listener, an application developer writes classes that implement listener interfaces for life cycle events, and the deployer configures these classes to be used by a Web application. The class files for the listeners are packaged in the Web archive, and configured using the deployment descriptor web.xml. A listener class must have a public constructor with no arguments. Each Web application can have multiple listeners of each type.

The interfaces provided for listening to Web application life cycle events are:

  • javax.servlet.ServletContextListener : The methods in this interface are called when a new servlet context is created or just before the servlet context is destroyed.

    There is a single ServletContext for each Web application, for each Java virtual machine. Because of this, a ServletContext is typically initialized when a Web application is deployed. The ServletContext is destroyed when a Web application is undeployed. The Web container calls ServletContextListener.contextInitialized when the Web application is ready to process request. The container calls the method contextDestroyed when the application is going to be shut down.

  • javax.servlet.http.HttpSessionListener : The methods in this interface are called when an HTTP session is created or destroyed. The call to the methods occurs after the session is created/invalidated.

    An HTTP session is associated with a single application client, and is often created only when requested by the application code. As mentioned earlier, the listener class, HttpSessionListener, has methods that are called at HTTP session and destruction. The class has two methods. The first method, sessionCreated, is called when the Web container creates the session. The second method, sessionDestroyed, is called when a session is destroyed. A session may be destroyed either explicitly by invalidation or by timeout.

  • javax.servlet.ServletContextAttributeListener : The methods in this interface are called when a servlet context attribute is created, modified, or removed from a servlet context.

    Operations on servlet context attributes can be monitored by implementing java.servlet.ServletContextAttributeListener in a listener class. The Web container calls interface methods attributeAdded, attributeReplaced, and attributeRemoved when servlet context attributes are added, replaced, or removed, respectively.

  • javax.servlet.http.HttpSessionAttributeListener : The methods in this interface are called when a session attribute is created, modified, or removed from an HTTP session.

    A listener class that implements java.servlet.http.HttpSessionAttributeListener is notified when there are changes to HTTP session attributes. The Web container calls interface methods attributeAdded, attributeReplaced, and attributeRemoved when HTTP session attributes are added, replaced, or removed, respectively.

  • javax.servlet.http.HttpSessionBindingListener : The methods in this interface are called when an object is bound or unbound from an HTTP session attribute.

    If an object being added or removed to the session implements HttpSessionBindingListener, the Web container calls the binding listener's valueBound or valueUnbound method to notify the object of the change.

  • javax.servlet.http.HttpSessionActivationListener : Allows objects bound to session attributes to listen for session passivation or activation.

Creating a new listener class

The Life-cycle Listener wizard enables you to create Java listener classes for various J2EE listener types related to servlet context and session events and attributes

To create a listener class, do the following:

  1. To launch the Life-cycle Listener wizard, from the Web perspective select File > New > Life-cycle Listener.

  2. On the first page, supply the following:

    • Specify the folder where the listener class will be placed, the package (com.titan.listeners) that the class will belong to (it is added into a default package if you do not specify one), and a name for the listener. The Class name value should be the class name of the listener (TitanListener).

      NOTE: You should place the listener in the Java source folder.

    • Specify a Superclass for the listener class. A listener created by this wizard can have Object, or any class that has Object in its hierarchy, as its superclass. Click Browse to choose from the available superclasses.

    Life-cycle Listener
  3. Click Next.

  4. Select a modifier to specify whether your listener classes are public, abstract, or final. (Classes cannot be both abstact and final.)

  5. You can also add additional interfaces to implement in addition to the default interfaces. Click Add to open the Interface Selection dialog. In this dialog, as you type the name of the interface that you are interested in adding in the Choose interfaces field, the list of available interfaces listed in the Matching types list box updates dynamically to display only the interfaces that match the pattern. Choose an interface to see the Qualifier and click Add. Click OK when you are finished.

  6. Choose which method stub you want to create. The Inherited abstract methods and Constructors from superclass options add stubs for inherited abstract methods and superclass constructors that must be implemented (unless you intend to create an abstract listener). One method with the Inherited abstract methods option must be created for the class not to be abstract.

  7. If you select the Add to web.xml check box, the generated listeners will be automatically included in the Web project web.xml file.

    Life-cycle Listener
  8. Click Finish.

    Life-cycle Listener

The listener class that you requested is generated and added to the Java package that you designated under the Java source folder.

The sample code defines listeners for two types of events: servlet context creation/destruction, session creation/destruction. Each method simply prints its name to standard output, to indicate that the callback to the method occurred. The callbacks print feedback to the server process's standard output unit.

public void contextInitialized(ServletContextEvent arg0) {
	System.out.println("TitanListener: contextInitialized");
}
					
public void contextDestroyed(ServletContextEvent arg0) {
	System.out.println("TitanListener: contextDestroyed");
}
					
public void sessionCreated(HttpSessionEvent arg0) {
	System.out.println("TitanListener: sessionCreated");
}					
					
public void sessionDestroyed(HttpSessionEvent arg0) {
	System.out.println("TitanListener: sessionDestroyed");
}					
					

Configuring Listener Classes

Listener classes are declared using the <listener> tag in the deployment descriptor file, web.xml:


<listener>
	<listener-class>com.titan.listeners.TitanListener</listener-class>
</listener>

					

The Web container is responsible for creating and providing callbacks to instances of the listener classes.

You will see the output from listener classes in server's console when you start web application and invoke any servlet or JSP participating in HTTP session:

[17.08.05 16:28:37:606 EEST] 3dfe181b WebContainer  A SRVE0169I: Loading Web Module: titan-web.
[17.08.05 16:28:37:653 EEST] 3dfe181b SystemOut     O TitanListener: contextInitialized
...
[17.08.05 16:33:14:131 EEST]  a151819 WebGroup      I SRVE0180I: [titan-web] [/titan-web] [Servlet.LOG]: /index.jsp: init
[17.08.05 16:33:14:162 EEST]  a151819 SystemOut     O TitanListener: sessionCreated
...
[17.08.05 16:33:48:286 EEST]  9085819 SystemOut     O TitanListener: sessionDestroyed
[17.08.05 16:33:48:286 EEST]  9085819 SystemOut     O TitanListener: contextDestroyed					
					
Advertisement


DMCA.com