Recipe 19.4 on changing the order filters are applied to a servlet; Recipe 19.5 on configuring filter initialization parameters; Recipe 19.6 on blocking requests; Recipe 19.7 onfiltering
Trang 3Recipe 19.4 on changing the order filters are applied to a
servlet; Recipe 19.5 on configuring filter initialization
parameters; Recipe 19.6 on blocking requests; Recipe 19.7 onfiltering the HttpServletResponse; Recipe 19.8 on using filterswith RequestDispatchers; Recipe 19.9 on using filters to checkrequest parameters; Recipe 19.10 on using filters to disallowrequests from certain IP addresses
Trang 6is the only servlet path to which this filter is applied As youmight have guessed, the LogFilter logs some information
about the request before the request continues along to itsservlet destination Example 19-2 shows the filter class for the
LogFilter in Example 19-1
This filter class provides the additional benefit of showing you how to log a message inside of a filter!
Make sure to:
Create the filter with a constructor that does not take anyparameters
Trang 7//load the configuration for this application's loggers using the // servletLog.properties file
Trang 9HttpServletResponse; Recipe 19.8 on using filters with
RequestDispatchers; Recipe 19.9 on using filters to checkrequest parameters; Recipe 19.10 on using filters to disallowrequests from certain IP addresses
Trang 10ServletRequest parameter has the getParameter,
getParameterMap, getParameterNames, and
getParameterValues methods which allow the filter to peek at
a servlet's parameters and values
First, you have to map the Filter you have designed to the
servlet This chunk of web.xml maps a Filter object to a
servlet named Viewer
<! any context-param elements go here >
Trang 11made to the Viewer servlet before the servlet processes the
request
"Only one instance per filter declaration in the deployment descriptor is instantiated per Java virtual machine of the container," according to the Servlet v2.4 specification, Chapter SRV.6.2.1.
Example 7-14 gets access to the parameters in the intercepted
request by calling ServletRequest.getParameterMap( )
However, you are free to use other ServletRequest API
methods to look at parameters, such as
returns a java.util.Map of parameter names and values,
which you extract from the Map using a java.util.Iterator
and its next( ) method
Trang 12The call Map.entrySet( ) returns a java.util.Set , from which you obtain an Iterator by calling Set.iterator( ) The objects returned from the Iterator.next( ) method in this case are Map.Entry objects that hold key/value pairs, relating to the parameter names and values.
this.config = filterConfig;
}
Trang 13public void doFilter(
ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException {
Trang 15Recipe 11.11 Using a Filter to Monitor Session Attributes
Problem
You want to use a filter to check a session attribute prior to therequest reaching a servlet
Solution
Create a Java class that implements javax.servlet.Filter,write session-related code in the class's doFilter( ) method,then configure the filter in your deployment descriptor
Discussion
Filters, as their name suggests, are semipermeable barriersthrough which requests to your web application must pass
before they reach servlets, JSPs, or even static content Filtersare technically Java classes that implement the
request and response objects
Filters are configured in web.xml In Example 11-18, a filter
checks a logged-in HttpSession attribute, and logs its
Trang 16activities by calling the ServletContext object's log( )
Trang 17}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException {
// log the session ID
Trang 18// Find out whether the logged-in session attribute is set String logged = (String) session.getAttribute("logged-in");
The init( ) method displays a console message when its
Trang 19for log files with names such as localhost_home_log.2003-01-24.txt Here is an example of the log entries for this filter:
2003-01-24 11:56:09 doFilter called in: SessionFilter on Fri Jan 24 11:56:09 EST 20032003-01-24 11:56:09 session ID: E04DE93D9B88A974ED2350BCF7945F34
2003-01-24 11:56:09 log-in status: no
The filter gets access to the session with this code:
HttpSession session = ((HttpServletRequest) request).getSession( );
Since the doFilter( ) method has a ServletRequest
parameter type, and not a HttpServletRequest type, the
certain session attribute (logged-in) If
session.getAttribute("logged-in") returns null, this
attribute is added to the session with the value "no" The code
then calls chain.doFilter(request,response) inside of the
filter's doFilter( ) method
This method call on the FilterChain object ensures that the
Trang 21The requests for this servlet will not pass through the mapped filter first, however, if the servlet is requested with an "invoker"-style URL of the form
Trang 22http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/http/HttpSession.htmlChapter 1 on web.xml; Chapter 6 of the Servlet v 2.3 and 2.4
specifications on filtering
Trang 23Headers
Problem
You want to use a filter to change the request headers before aservlet or JSP receives the request
Solution
Wrap the request in your own custom request class Pass therequest wrapper or decorator class to the
Trang 24}
Trang 25
ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException {
Trang 27) :
//does not return the new parameter value //added by the overridden getQueryString //method
Trang 29Recipe 19.3 Mapping More Than One Filter to a Servlet
Problem
You want requests for a servlet or JSP to pass through morethan one filter
Solution
Map each filter to the servlet or JSP using filter-mapping
elements in the deployment descriptor The filters are applied tothe servlet in the order they appear in the deployment
descriptor
Discussion
Your web application may define several different filters with aspecific purpose For instance, one filter might log messages,while another filter authenticates users It is straightforward tocreate a filter chain that applies each filter in a specified order
to a servlet You use the filter-mapping element to map eachfilter to the target servlet (or JSP) The web container then
applies the filters to the target in the order that the mapping elements are defined in the deployment descriptor.Example 19-4 configures two filters: AuthenFilter and
filter-LogFilter The filter-mapping elements for these filters thenmap the servlet name requestheaders to each of these filters.The order of the filter-mapping elements in Example 19-4
Trang 30applied to the servlet named requestheaders first, followed by
Trang 32HttpServletResponse; Recipe 19.8 on using filters with
RequestDispatchers; Recipe 19.9 on using filters to checkrequest parameters; Recipe 19.10 on using filters to disallowrequests from certain IP addresses
Trang 33Recipe 19.4 Changing the Order in Which Filters are Applied to Servlets
Problem
You want to change the order in which filters are applied to webcomponents
Trang 34HttpServletResponse; Recipe 19.8 on using filters with
RequestDispatchers; Recipe 19.9 on using filters to check
request parameters; Recipe 19.10 on using filters to disallowrequests from certain IP addresses
Trang 35<param-value>A102003</param-value>
Trang 38}
Here is how the log output appears:
INFO - Log id:A102003: Request received from: localhost for http://localhost:8080/home/requestheaders
You can also use the FilterConfig object's getInitParameterNames
Trang 39request and issues a response itself
Trang 40}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if (authenticated){
Trang 42false to demonstrate the filter's response to the client Thefilter uses the PrintWriter from the
to the doFilter( ) method The PrintWriter sends HTMLback to the client Figure 19-1 shows the response output in aweb browser
Figure 19-1 The HTML page returned by a
blocking filter
If you regularly use filters to send responses to a client, consider creating a JavaBean to customize the response Store the bean class in
its package beneath WEB-INF/classes, and use the bean inside the
filter.
See Also
Recipe 7.9 on using a filter to read request parameter values;Recipe 11.11 on using a filter to monitor session attributes;
Trang 43Recipe 18.3 on using a filter to alter then forward the request;Recipe 19.1-Recipe 19.4 on mapping filters to web components;Recipe 19.5 on configuring init parameters for a filter; Recipe19.7 on filtering the HTTP response; Recipe 19.8 on using filterswith RequestDispatchers; Recipe 19.9 on using filters to checkrequest parameters; Recipe 19.10 on using filters to disallowrequests from certain IP addresses.
Trang 44Problem
You want to change the response with a filter while the clientrequest is en route to the servlet
Trang 45Example 19-9 shows the Java class that we will use to wrap theresponse object
If you are just making a simple response change, you do not have to
go to the trouble of using an HttpServletResponseWrapper class This code inside of a filter's method adds a header to the response, then calls the chain.doFilter( ) method with the altered response:
if(response instanceof HttpServletResponse){
//cast to HttpServletResponse to call //addHeader
myHttpResponse = ((HttpServletResponse)response);
myHttpResponse.addHeader("WWW-Authenticate", "BASIC realm=\"Admin\"");
chain.doFilter(request,response); }
The ResponseWrapper class contains the skeleton of a new
method named getWebResource I want to show the mechanics
of wrapping the response in a filter, so have kept this wrapperclass very simple
All the other HttpServletResponse-derived method calls aredelegated to the wrapped response object, which is the
convenience of extending HttpServletResponseWrapper
Example 19-9 An HttpServletResponseWrapper class for use in a filter
package com.jspservletcookbook;
import javax.servlet.*;
import javax.servlet.http.HttpServletResponseWrapper;import javax.servlet.http.HttpServletResponse;
Trang 46that uses this ResponseWrapper class
The class extending HttpServletResponseWrapper must be placed
if(response instanceof HttpServletResponse){
Trang 49xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://java.sun.com/xml/ns/j2ee
The dispatcher elements in the example configuration specify
that the LogFilter applies to requests for the servlet path
/requestheaders, as well as to any RequestDispatchers that
Trang 51This type of RequestDispatcher set-up is only supported by Servlet API v2.4 and above.
See Also
Chapter 6 on including content using RequestDispatchers;Recipe 7.9 on using a filter to read request parameter values;Recipe 11.11 on using a filter to monitor session attributes;
Recipe 18.3 on using a filter to alter then forward the request;Recipe 19.1-Recipe 19.4 on mapping filters to web components;Recipe 19.5 on configuring init parameters for a filter; Recipe
Trang 52parameters; Recipe 19.10 on using filters to disallow requestsfrom certain IP addresses
Trang 53Recipe 19.9 Checking Form Parameters with a Filter
Discussion
Filters offer an alternative to JavaScript and other server-sidelanguages for checking whether the user has entered valid
values into HTML form fields The filter in this recipe initiates abasic check of the request parameters to determine if they are
null or the empty String
Example 19-13 is a JSP that contains an HTML form The JSPincludes some embedded JSTL tags that fill in the text fieldswith any correct values if the form is returned to the user forcorrections In most cases, a user fills in the vast majority ofthe fields correctly, but might make a mistake in one or two ofthem You do not want to make him fill out all of the fields
again
Example 19-13 A JSP containing a form for users
Trang 57//Create an error message; store it in a request attribute
request.setAttribute("errorMsg",
"Please make sure to provide a valid value for all of the text "+ "fields.");
Enumeration params = request.getParameterNames( );
Trang 58
//Create request attributes that the form-related JSP will //use to fill in the form fields that have already been
//filled out correctly Then the user does not have to fill //in the entire form all over again
Trang 60Chapter 6 on including content using RequestDispatchers;Recipe 19.8 on using filters with RequestDispatchers; Recipe7.9 on using a filter to read request parameter values; Recipe18.3 on using a filter to alter then forward the request; Recipe19.1-Recipe 19.4 on mapping filters to web components; Recipe19.5 on configuring init parameters for a filter; Recipe 19.6 onblocking a request; Recipe 19.7 on filtering the HTTP response
Trang 61Problem
You want to use a filter that checks the IP address associatedwith the request
Trang 64//Client is okay; send them on their merry way chain.doFilter(request,response);
Trang 6619.4 on mapping filters to web components; Recipe 19.5 onconfiguring init parameters for a filter; Recipe 19.7 on filteringthe HTTP response; Recipe 19.9 on checking form parameterswith a filter.
Trang 67Recipe 14.8 Logging Messages Using a Session EventListener
Trang 68Recipe 7.1 Handling a POST HTTP Request in a Servlet
The service method of a servlet calls the servlet's doPost
method when a client sends a POST HTTP request The servletdeveloper then has four different methods she can call to gainaccess to the posted data, which makes it pretty easy to
process these requests Just in case a client application uses a
GET method to send the servlet its data as a query string, theservlet should also call:
doPost(request,response);
in the servlet's doGet( ) method Example 7-2 demonstrateshandling POST data with the oft-used getParameter(Stringname) method, as well as with the getParameterMap( )
method, which returns a java.util.Map The map contains
Trang 69method returns a java.util.Enumeration of the parameternames You can iterate through this Enumeration and pass thevalues to getParameter(String name) Another
returns a String array of all the posted values for that
parameter name (if there is only one value, the returned array
contains one String) Figure 7-1 shows the browser display ofthe PostHandler servlet after a user has submitted the form inExample 7-1
Trang 71//the keys of the Map.Entry objects are type String; the values are //type String[],
Trang 72servlet prints "Unknown"; otherwise, it prints the name value
Then the code gets a java.util.Iterator from the
java.util.Set returned from Map.entrySet( ) The Set
contains Map.Entry objects, which are key/value pairs
representing the parameter name and value The servlet uses
the iterator to cycle through the parameter names and values:
Iterator iterator = param_map.entrySet( ).iterator( );
Trang 73to deal with them, such as a validator bean that takes a Map as
Trang 74a Query String
Problem
You want to use a servlet to add one or more parameters to aquery string, then forward the request to its final destination
Solution
Use the HttpServletRequest API to get the existing query
string Then append any new parameters to the query stringand use a javax.servlet.RequestDispatcher to forward therequest
Discussion
The servlet in Example 7-12 simply takes any existing querystring and appends the parameters that it has to add to this