® ibm software group © 2007 ibm corporation servlet filtering 4.1.0.3
TRANSCRIPT
®
IBM Software Group
© 2007 IBM Corporation
Servlet Filtering
4.1.0.3
2
After completing this unit, you should be able to: Describe the processing flow for filters List the Servlet API interfaces and support object used to
implement filters Create a new filter using Rational Application Developer Create deployment descriptor entries for a filter Develop a basic filter using the appropriate interfaces Develop a filter that blocks normal filter chain execution Develop a filter using a wrapped custom response object
After completing this unit, you should be able to: Describe the processing flow for filters List the Servlet API interfaces and support object used to
implement filters Create a new filter using Rational Application Developer Create deployment descriptor entries for a filter Develop a basic filter using the appropriate interfaces Develop a filter that blocks normal filter chain execution Develop a filter using a wrapped custom response object
Unit objectives
3
Introducing Filters Reusable components Transform (or filter) the content of HTTP requests, responses, and
headers Can be configured into chains of multiple filters Are indirectly invoked by client request for a Web resource
Requested Web resource is at the end of the chain Types of functionality:
Process the request for a resource before it is invokedProcess the response for a resource after it is invokedModify the response or request object for a Web resource by
wrapping the objects in a custom objectTransfer control to next filter or Web resource in chainBlock execution of the filter chain
4
Typical Uses of Filters The Servlet Filtering Specification notes the following as
examples of typical filter uses:Authentication filtersLogging and auditing filtersImage conversion filtersData compression filtersEncryption filtersTokenizing filtersFilters that trigger resource access eventsXSLT filters to transform XML contentMIME-type chain filtersCaching filters
5
Filter Processing Flow
Web Resource Requested by Client
Request Response
Access/Modify Request
doFilter()
Access /Modify Response
Filter
Client Request for Web Resource
Container
6
Filter Chain Processing Filters can be configured in a chain A FilterChain object describes the chain Filters are invoked via nested calls
Web container invokes doFilter() in first filter in chain Class: Implementation of javax.servlet.Filter Parameters:
– Request of type ServletRequest– Response of type ServletResponse – Chain of type FilterChain
First filter in chain calls doFilter() to invoke next filter in chain Referenced from input FilterChain object Class: javax.servlet.FilterChain Parameters:
– Request of type ServletRequest– Response of type ServletResponse
Last entry in the chain is the Web resource
7
doFilter() Nested Calls
doFilter() {
chain.doFilter()
}
doPost() {
……
…….
}
doFilter() {
chain.doFilter()
}
FirstFilter
SecondFilter
FilteredServlet
http://example.com/app/FilteredServlet
Request
Response
8
Typical doFilter() Pattern Examine request object Possibly wrap request or response object in new custom
object Invoke next filter in chain with doFilter() method
Possibly with wrapped objectsMay end chain by not performing this step
Filter must complete response object
Process response object
9
Implementing a Filter Create a class that implements the javax.servlet.Filter interface Implement methods:
init()doFilter()destroy()
Describe the filter in the deployment descriptor with the filter element
Configure the filter’s chaining configuration in the deployment descriptor with the filter-mapping element
10
Application Developer Filter Support Creating a filter in Web Perspective
Right-click on the Web project and click New Filter Creates a class that implements javax.servlet.Filter Creates the following methods in the class:
initdoFilterdestroy
Creates entries in deployment descriptor to define filter:filterfilter-mapping
11
Creating a New Filter in Application Developer
Click Next
12
The javax.servlet.Filter Interface
Three methods comprise the interface:init() throws ServletException
Purpose: To perform filter initialization Called by container to indicate filter is being placed in service Parameter:
– config of type FilterConfig
doFilter() throws ServletException, IOException Purpose: To perform the filtering Called by the container each time a request/response pair is passed through the
chain due to a client request for a resource at the end of the chain Parameters:
– Request of type ServletRequest– Response of type ServletResponse– Chain of type FilterChain
destroy() Purpose: To perform filter cleanup. Called by container to indicate filter is being placed out of service No parameters
13
The javax.servlet.FilterConfig Interface
There are four getter methods in the interface:getFilterName()
Returns the String name of the filter
getInitParameter() Returns the the String value of a initialization parameter Input: name of type String
getInitParameterNames() Returns an enumeration of String with the names of the initialization
parameters
getServletContext() Returns a reference to the ServletContext in which the filter is
operating
14
The javax.servlet.FilterChain Interface
The interface consists of one method:doFilter() throws ServletException
Purpose: invoke the next filter in the chain Called by the container each time a request/response pair is passed
through the chain due to a client request for a resource at the end of the chain
Inputs:– Request of type ServletRequest– Response of type ServletResponse
15
Describing the Filter
Filters are described in the deployment descriptor (web.xml) Structure of the filter’s describing elements
<filter>: describes the filter <filter-name>: name of the filter <filter-class>: name of the implementing class <init-param>: describes initialization parameters of the filter
– <param-name>: the initialization parameter name– <param-value>: the initialization parameter value
16
Example of a Filter Description
<filter> <display-name>FormChecker</display-name> <filter-name>FormChecker</filter-name> <filter-class>
com.ibm.filters.FormChecker </filter-class> <init-param> <param-name>__FORM_NAME</param-name> <param-value>Prime Finder</param-value> </init-param> <init-param> <param-name>num</param-name> <param-value>Number</param-value>
</init-param></filter>
17
Describing the Filter Mapping
Filter mappings are described in the deployment descriptor (web.xml)
Structure of the filter’s mapping elements<filter-mapping>: describes the filter
<filter-name>: name of the filter to be mapped <servlet-name>: name of the resource to apply this filter
OR <url-pattern>: URL pattern of the resource to apply this filter
18
Examples of Filter Mapping
<filter-mapping> <filter-name>Logger</filter-name> <servlet-name>Prime</servlet-name>
</filter-mapping>
<filter-mapping> <filter-name>WelcomeTrailer</filter-name> <url-pattern>/Welcome.jsp</url-pattern>
</filter-mapping>
19
Configuring Filters with Application Developer
Configure filters in the Web Deployment Descriptor EditorFilters tabSource tab
20
Configuring Filter Chaining Determined by order of filter-mapping elements in the
deployment descriptor Last filter in chain invokes the requested Web resource Rules:
First, get filters that match url-pattern element of requested Web resource
Second, get filters that match servlet-name element of requested Web resource
In each case, the filter’s order in the chain is determined by its order in the deployment descriptor file
21
Example of Configuring Filter Chaining
<filter-mapping>
<filter-name>FormChecker</filter-name>
<servlet-name>Prime</servlet-name>
</filter-mapping>
<filter-mapping>
<filter-name>Logger</filter-name>
<url-mapping>/*</url-mapping>
</filter-mapping>
<filter-mapping>
<filter-name>PrimeTrailer</filter-name>
<servlet-name>Prime</servlet-name>
</filter-mapping>Mapping Order for Prime Servlet:
(1) Logger
(2) FormChecker
(3) PrimeTrailer
22
Configuring Filters for Reuse Filters are designed to be reusable components Same implementation class can be used for different filters
Different filter-name elementPossibly different init-param element
Container instantiates an instance of the class for each <filter> element
public class AuditFilter implements Filter {
private int mode = 0;
public void init(FilterConfig arg0) throws ServletException { String modeStr = arg0.getInitParameter("mode"); if (modeStr.equals("FULL")) { mode = FULL; } ... }...
<init-param> <param-name>mode</param-name> <param-value>FULL</param-value></init-param>
23
Example of Configuring Filter Reuse
<filter> <filter-name>WelcomeTrailer</filter-name> <filter-class>com.ibm.filters.Trailer</filter-class> <init-param> <param-name>msg</param-name> <param-value>
Watch for our new Web Site! </param-value> </init-param>
</filter>
<filter> <filter-name>DatabaseTrailer</filter-name> <filter-class>com.ibm.filters.Trailer</filter-class> <init-param> <param-name>msg</param-name> <param-value>
Sorry, but the database is currently down. </param-value> </init-param>
</filter>
24
Filters with RequestDispatcher Ability to configure filters that are invoked under
RequestDispatcher with forward() and include() calls
Request
Filters
Forward / IncludeFilters
Web Resource
Filters
Response
Request
Response
Servlet v2.4
Servlet v2.3
Web Resource
Web Resource
Web Resource
Forward / Include
25
Dispatcher Element New <dispatcher> element in the Deployment Descriptor:
REQUEST filter if request is directly from a client
FORWARD filter if request is from RequestDispatcher.forward() method
INCLUDE filter if request is from RequestDispatcher.include() method
ERROR filter if request is due to error redirection mechanism
REQUEST is the default when no <dispatcher> element<filter-mapping>
<filter-name>Customer Filter</filter-name>
<url-pattern>/customers/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>Account Filter</filter-name>
<servlet-name>CustomerServlet</servlet-name>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
26
Filter Code Examples Example Filters:
Logger: A simple filter that performs elapsed execution time logging for a servlet
FormChecker: A filter to check form syntax; blocks execution of the chain if form is not correct
Trailer: A filter that appends a message to the end of Web resource’s response page; uses a custom response object
27
Logger Filter: Function Description
A simple logging filter Calculates servlet’s execution time in milliseconds Displays the time in the server’s event log
28
Logger Filter: Deployment Descriptor
<filter> <filter-name>Logger</filter-name> <display-name>Logger</display-name> <filter-class>
com.ibm.filters.Logger </filter-class></filter>
29
Logger Filter: init() and destroy() Methods
package com.ibm.filters;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;
public class Logger implements Filter {
FilterConfig config;
public void init(FilterConfig arg0) throws ServletException { config = arg0;}
public void destroy() {}
30
Logger Filter: doFilter() Method
public void doFilter (ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws ServletException, IOException {
long before = System.currentTimeMillis();
arg2.doFilter(arg0, arg1);
long duration = System.currentTimeMillis()- before; String msg = “Servlet duration: " +
duration + “milliseconds"; config.getServletContext().log(msg);}
31
Logger Filter: How It Works Gets timestamp from system Uses the doFilter() method of FilterChain object to invoke
next filter Upon return from doFilter(), calculates duration Composes message with duration Uses the config object (FilterConfig) to get the servlet context Uses the ServletContext.log() method to write message to
the servlet’s event log
32
FormChecker Filter: Function Description
Checks that specified fields in a form have non-empty values Filters a servlet that is the Action URL for a FORM tag Field names are entered as the filter’s init-param names
Example: <param-name>firstname</param-name> Field labels are entered as the filter’s init-param values
Example: <param-value>First Name</param-value> Parameter name __FORM_NAME is reserved
Value is the name of the form (for example, Order Entry Form) If one or more errors is found, the filter forwards the list of missing
fields to a JSP page that lists the form’s name and the form fields that are missing or have empty values
33
FormChecker Filter: Deployment Descriptor
<filter> <filter-name>FormChecker</filter-name> <display-name>FormChecker</display-name> <filter-class>com.ibm.filters.FormChecker</filter-class> <init-param> <param-name>__FORM_NAME</param-name> <param-value>Prime Finder</param-value> </init-param> <init-param> <param-name>num</param-name> <param-value>Number</param-value> </init-param>
</filter><filter-mapping> <filter-name>FormChecker</filter-name> <servlet-name>Prime</servlet-name></filter-mapping>
34
FormChecker Filter: init() and destroy() Methods
package com.ibm.filters;import java.io.IOException;import java.util.ArrayList;import java.util.Enumeration;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;
public class FormChecker implements Filter { FilterConfig config;
public void init(FilterConfig arg0) throws ServletException { config = arg0; }
public void destroy() { }
35
FormChecker: doFilter() Method (1 of 2)public void doFilter(ServletRequest arg0,
ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
boolean doChain = true;
ArrayList fieldList = new ArrayList();
Enumeration mandatory = config.getInitParameterNames();
if (mandatory != null) {
while (mandatory.hasMoreElements()) {
String parmName = (String) mandatory.nextElement();
if (!parmName.equals("__FORM_NAME")) {
String parmValue = arg0.getParameter(parmName);
String fieldName = "";
if (parmValue == null || parmValue.length() == 0) {
doChain = false;
fieldName = config.getInitParameter(parmName);
fieldList.add(fieldName);
}
}
}
}
36
FormChecker Filter: doFilter() Method (2 of 2)
if (doChain) { arg2.doFilter(arg0, arg1); } else { String formNameValue = config.getInitParameter("__FORM_NAME"); String formName =
(formNameValue == null) ? "Form" : formNameValue; arg0.setAttribute("formname", formName); arg0.setAttribute("fieldlist", fieldList); config.getServletContext().getRequestDispatcher
("/BadForm.jsp").forward(arg0, arg1); }
}}
37
FormChecker Filter: How It Works Mandatory field names are read from the filter’s init-param values
as an Enumeration Each init-param is tested to see if the request parameter of that
name exists and is non-emptyIf the parameter does not exist or is empty, then the field name
(value of the init-param) is added to a list and the doChain flag is set to false (blocking the request)
If all mandatory fields are non-empty, doFilter() passes control to the next filter on the chain, and ultimately to the Prime servlet
Otherwise, the chain is blockedThe array list of missing field names and the form name (value
of __FORM_NAME init-param) are put into request attributesControl is forwarded to a JSP file to construct an error page
38
Wrapping Request and Response Objects Filters may wrap the request and response objects to create
new custom request and response objects The wrapped objects might:
Override existing methods Create new methods
Custom request and response objects are typically created by extending :HttpServletRequestWrapperHttpServletResponseWrapper
Subsequent methods in the filter chain have access to these new custom objects created by wrapping
39
Trailer Filter: Function Description Appends a message to the end of the response object The message is stored as a filter init-param A custom response object is created:
Extends HttpServletResponseWrapperBuffers response in a StringWriterOverrides:
toString() : extracts StringWriter buffer as a String getWriter(): returns PrintWriter based on the StringWriter
Subsequent filters use the custom getWriter() method The custom response object is passed to the chain instead of the original
response object After return from the chain, the response is unwrapped, the message is
added to it, and both are written to the original response object
40
Trailer Filter: Deployment Descriptor
<filter> <filter-name>WelcomeTrailer</filter-name> <display-name>Welcome Trailer</display-name> <filter-class> com.ibm.filters.Trailer </filter-class> <init-param> <param-name>msg</param-name> <param-value> Watch for our new Web Site coming soon! </param-value> </init-param></filter>
<filter-mapping> <filter-name>WelcomeTrailer</filter-name> <url-pattern>/Welcome.jsp</url-pattern></filter-mapping>
41
Trailer Filter: init() Method
package ibm.com.filters;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletResponse;
public class Trailer implements Filter {
private String msg = ""; private FilterConfig config;
public void init(FilterConfig arg0) throws ServletException { config = arg0; msg = config.getInitParameter("msg"); }
42
Trailer Filter: doFilter() Methodpublic void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException {
StringResponse strResp = new StringResponse((HttpServletResponse) arg1); arg2.doFilter(arg0, strResp); PrintWriter out = arg1.getWriter(); String responseString = strResp.toString(); int endBodyIndex = responseString.indexOf("</BODY>"); if (endBodyIndex > -1) { StringBuffer finalResponse = new StringBuffer(responseString.substring(0, endBodyIndex - 1)); finalResponse.append("<P>"); finalResponse.append(msg); finalResponse.append("</P></BODY></HTML>"); String finalResponseString = finalResponse.toString(); out.write(finalResponseString); } else { out.write(responseString); } out.close();}
43
Custom Response: StringResponse
package ibm.com.sw284.filters;import java.io.PrintWriter;import java.io.StringWriter;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpServletResponseWrapper;
public class StringResponse extends HttpServletResponseWrapper {
private StringWriter responseWriterBuffer; public StringResponse(HttpServletResponse resp) { super(resp); responseWriterBuffer = new StringWriter(); } public String toString() { return responseWriterBuffer.toString(); } public PrintWriter getWriter() { return new PrintWriter(responseWriterBuffer); }}
44
Trailer Filter: How It Works New instance of custom response object (StringResponse) created Wrapped response passed to next filter (Welcome.jsp) via chain.doFilter() The toString() method of the StringResponse object extracts the response
created by Welcome.jsp The </BODY> tag is searched for in the extracted response Assuming the </BODY> tag is found:
A substring of the response up to the </BODY> tag is createdThe message is added to the substring New </BODY> and </HTML> tags are addedThe new response is sent to the original request’s PrintWriter
Otherwise, an unmodified response is sent to the PrintWriter
45
Checkpoint
1. What interface is implemented to build a filter?2. What object defines the sequence of filter execution? 3. How can a filter change the flow of processing to other
filters?4. What is the position of the user-requested Web resource on
the filter chain? 5. How many instances of a filter does the web container
create?
46
Checkpoint solutions
1. The javax.servlet.Filter interface is implemented to build a filter.
2. The FilterChain object defines the sequence of filter execution. The container passes an object of this type to the first filter. The execution is defined by the filter-mapping elements in the deployment descriptor. The order of execution is determined by the order of matching filter-mapping elements in the deployment descriptor.
3. A filter can control the flow of processing by not calling the FilterChain.doFilter() method. In this case, it is responsible for providing the response object.
4. The requested Web resource is last on the filter chain.5. The container produces one instance of a filter for each
filter element defined in the deployment descriptor.
47
Having completed this unit, you should be able to: Describe the processing flow for filters List the Servlet API interfaces and support object used to
implement filters Create a new filter using Rational Application Developer Create deployment descriptor entries for a filter Develop a basic filter using the appropriate interfaces Develop a filter that blocks normal filter chain execution Develop a filter using a wrapped custom response object
Having completed this unit, you should be able to: Describe the processing flow for filters List the Servlet API interfaces and support object used to
implement filters Create a new filter using Rational Application Developer Create deployment descriptor entries for a filter Develop a basic filter using the appropriate interfaces Develop a filter that blocks normal filter chain execution Develop a filter using a wrapped custom response object
Unit summary