Filters are a feature that was introduced in version 2.3 of the servlet specification. A filter is a special type of servlet that dynamically intercepts requests and responses and transforms the information contained in them. The main advantage of a filter is that it can be added to existing applications without any need for recompilation.
Filters can have several important uses:
To encapsulate recurring tasks in reusable units
To format the data sent back to the client
To provide authorization and blocking of requests
To provide logging and auditing
A filter can perform filtering tasks on the request, the response, or both.
A filter is still a servlet, so it extends HttpServlet but it also implements the javax.servlet.Filter interface.
Instead of doGet() or doPost(), filter tasks are done in a doFilter() method.
So that a filter can access initialization parameters, it is passed a FilterConfig object in its init() method. A filter can access the ServletContext through the FilterConfig object and thereby load any resources needed for the filtering tasks.
Filters can be connected together in a FilterChain. The servlet container constructs the filter chain in the order the filters appear in the deployment descriptor.
Because filters are added to an application at deploy time, it is possible to map a filter to one or more servlets. This is illustrated in Figure 12.15, where the AuthenticateUser filter is applied to all servlets. The PageCounter is mapped to VerifyData and HTMLPage, and the EncodeResponse filter only affects requests to the AgencyTable servlet.
After a filter successfully completes its task, it must then call the doFilter() method on the next filter in the chain. The filter chain object is passed to the filter by the server as a parameter to the doFilter() method.
public void doFilter(ServletRequest req,ServletResponse res,FilterChain chain) throws IOException, ServletException { .. // filter code chain.doFilter(req, res); // call the next filter in the chain }
If it is the last filter in the chain, instead of invoking another filter, the container will invoke the resource at the end of the chain (a normal servlet). If for some reason the filter processing fails, and if it is no longer appropriate to continue servicing the request, there is no need to call doFilter() on the next filter in the chain; typically you will forward the request to an error handling page if filter chaining is inappropriate.
In a filter, you must provide an init(FilterConfig) method. This init(FilterConfig) method is called by the Web server when a filter is being placed into service, and it must complete successfully before the filter can do any filtering work.
The destroy() method is called when a filter is being taken out of service, and gives the filter an opportunity to clean up any resources.
The use of these methods will be shown in the following example.
The filter in Listing 12.8 logs the number of times the application is accessed. A similar technique could be used to intercept requests and authorize the user before calling the servlet to service the request.
Now all that is required is to update the HTMLPage servlet so that it outputs the value of the counter. This new servlet is called HTMLCounterPage and is shown in Listing 12.9.
You can add this servlet to your application examples as described in the next section.
Programming the filter is (as always) only half the task. Now it has to be deployed. In J2EE RI, this is achieved with the following steps:
1. | Add your servlet filter to the application examples using the New Web Component Wizard. Add the filter as you would with a normal servlet but you do not need to define an alias because the filter is not mapped onto a URL. |
2. | After creating the filter servlet select the Filter Mapping dialogue page for your Web Application and select Edit Filter List and then Add Filter as shown in Figure 12.16. Figure 12.16. deploytool Adding a Filter. |
3. | Returning to the Servlet Filter Mapping page select Add. On the pop-up window select the AuditFilter under Filter Name, select the Filter This Servlet option and set the Servlet Name to be HTMLCounterPage (see Figure 12.17). Figure 12.17. deploytool Servlet Filter Mapping.When you view the servlet deployment descriptor, you will see the following lines have been added: <filter> <filter-name>AuditFilter</filter-name> <filter-class>AuditFilter</filter-class> </filter> <filter-mapping> <filter-name>AuditFilter</filter-name> <servlet-name>HTMLCounterPage</servlet-name> </filter-mapping> |
4. | Deploy the application and when you access the HTMLCounterPage, the filter maintained counter will be incremented. |
This was a very simple example; more sophisticated filters can be used to modify the HTTP request before it is passed to the servlet or modify the HTTP response returned from the servlet.
18.117.158.165