net.sourceforge.stripes.controller
Class DynamicMappingFilter

java.lang.Object
  extended by net.sourceforge.stripes.controller.DynamicMappingFilter
All Implemented Interfaces:
Filter

public class DynamicMappingFilter
extends Object
implements Filter

A servlet filter that dynamically maps URLs to ActionBeans. This filter can be used to allow Stripes to dispatch requests to ActionBeans based on their URL binding, even if the URL to which they are bound is not explicitly mapped in web.xml.

One caveat must be observed when using this filter. This filter MUST be the last filter in the filter chain. When it dynamically maps an ActionBean to a URL, the filter chain is interrupted.

StripesFilter and/or DispatcherServlet may be declared in web.xml, but neither is required for this filter to work. If you choose not to declare StripesFilter in web.xml, then this filter should be configured the way you would normally configure StripesFilter. However, some resources, such as JSPs, may require access to the Stripes Configuration through StripesFilter. If you intend to access JSPs directly, then StripesFilter should be explicitly mapped to *.jsp.

This filter takes the following approach to determining when to dispatch an ActionBean:

  1. Allow the request to process normally, trapping any HTTP errors that are returned.
  2. If no error was returned then do nothing, allowing the request to complete successfully. If any error other than 404 was returned then send the error through. Otherwise ...
  3. Check the ActionResolver to see if an ActionBean is mapped to the URL. If not, then send the 404 error through. Otherwise...
  4. Invoke StripesFilter and DispatcherServlet

One benefit of this approach is that static resources can be delivered from the same namespace to which an ActionBean is mapped using clean URLs. (For more information on clean URLs, see UrlBinding.) For example, if your UserActionBean is mapped to @UrlBinding("/user/{id}/{$event}") and you have a static file at /user/icon.gif, then your icon will be delivered correctly because the initial request will not have returned a 404 error.

The IncludeBufferSize initialization parameter (optional, default 1024) sets the number of characters to be buffered by DynamicMappingFilter.TempBufferWriter for include requests. See DynamicMappingFilter.TempBufferWriter for more information.

This is the suggested mapping for this filter in web.xml.

  <filter>
      <description>Dynamically maps URLs to ActionBeans.</description>
      <display-name>Stripes Dynamic Mapping Filter</display-name>
      <filter-name>DynamicMappingFilter</filter-name>
      <filter-class>
          net.sourceforge.stripes.controller.DynamicMappingFilter
      </filter-class>
      <init-param>
          <param-name>ActionResolver.Packages</param-name>
          <param-value>com.yourcompany.stripes.action</param-value>
      </init-param>
  </filter>
  
  <filter-mapping>
      <filter-name>DynamicMappingFilter</filter-name>
      <url-pattern>/*</url-pattern>
      <dispatcher>REQUEST</dispatcher>
      <dispatcher>FORWARD</dispatcher>
      <dispatcher>INCLUDE</dispatcher>
  </filter-mapping>
 

Since:
Stripes 1.5
Author:
Ben Gunter
See Also:
UrlBinding

Nested Class Summary
static class DynamicMappingFilter.ErrorTrappingResponseWrapper
          An HttpServletResponseWrapper that traps HTTP errors by overriding sendError(int, ..).
static class DynamicMappingFilter.TempBufferWriter
           A Writer that passes characters to a PrintWriter.
 
Field Summary
static String CONTEXT_KEY_STRIPES_FILTER
          The attribute name used to store a reference to StripesFilter in the servlet context.
static String INCLUDE_BUFFER_SIZE_PARAM
          The name of the init-param that can be used to set the size of the buffer used by DynamicMappingFilter.TempBufferWriter before it overflows.
 
Constructor Summary
DynamicMappingFilter()
           
 
Method Summary
protected  void createStripesFilter(FilterConfig config)
          Create and initialize an instance of StripesFilter with the given configuration.
 void destroy()
           
 void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
           
protected
<T> T
eval(String expression, Node source, QName returnType)
          Evaluate an xpath expression against a DOM Node and return the result.
protected  Map<String,String> getFilterParameters(Node filterNode)
          Get the initialization parameters for a filter declared in web.xml.
protected  List<String> getFilterUrlPatterns(Node filterNode)
          Get all the URL patterns to which a filter is mapped in web.xml.
protected  String getRequestURI(HttpServletRequest request)
          Deprecated. Use HttpUtil.getRequestedPath(HttpServletRequest) instead.
protected  StripesFilter getStripesFilter()
          Get a reference to StripesFilter.
 void init(FilterConfig config)
           
protected  void initStripesFilter(HttpServletRequest request, HttpServletResponse response)
          The servlet spec allows a container to wait until a filter is required to process a request before it initializes the filter.
protected  void issueRequests(List<String> patterns, HttpServletRequest request, HttpServletResponse response)
          Issue a series of requests in an attempt to force an invocation (and initialization) of StripesFilter in the application context.
protected  Document parseWebXml()
          Parse the application's web.xml file and return a DOM Document.
 void requestRemotely(HttpServletRequest request, String relativePath)
          Issue a new request to a path relative to the request's context.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

INCLUDE_BUFFER_SIZE_PARAM

public static final String INCLUDE_BUFFER_SIZE_PARAM
The name of the init-param that can be used to set the size of the buffer used by DynamicMappingFilter.TempBufferWriter before it overflows.

See Also:
Constant Field Values

CONTEXT_KEY_STRIPES_FILTER

public static final String CONTEXT_KEY_STRIPES_FILTER
The attribute name used to store a reference to StripesFilter in the servlet context.

Constructor Detail

DynamicMappingFilter

public DynamicMappingFilter()
Method Detail

init

public void init(FilterConfig config)
          throws ServletException
Specified by:
init in interface Filter
Throws:
ServletException

destroy

public void destroy()
Specified by:
destroy in interface Filter

doFilter

public void doFilter(ServletRequest request,
                     ServletResponse response,
                     FilterChain chain)
              throws IOException,
                     ServletException
Specified by:
doFilter in interface Filter
Throws:
IOException
ServletException

getRequestURI

@Deprecated
protected String getRequestURI(HttpServletRequest request)
Deprecated. Use HttpUtil.getRequestedPath(HttpServletRequest) instead.

Get the context-relative URI of the current include, forward or request.


getStripesFilter

protected StripesFilter getStripesFilter()
Get a reference to StripesFilter. The first time this method is called, the reference will be looked up in the servlet context and cached in the stripesFilter field.


initStripesFilter

protected void initStripesFilter(HttpServletRequest request,
                                 HttpServletResponse response)
                          throws ServletException
The servlet spec allows a container to wait until a filter is required to process a request before it initializes the filter. Since we need to get a reference to StripesFilter from the servlet context, we really need StripesFilter to have been initialized at the time we process our first request. If that didn't happen automatically, this method does its best to force it to happen.

Parameters:
request - The current request
response - The current response
Throws:
ServletException - If anything goes wrong that simply can't be ignored.

parseWebXml

protected Document parseWebXml()
                        throws SAXException,
                               IOException,
                               ParserConfigurationException
Parse the application's web.xml file and return a DOM Document.

Throws:
ParserConfigurationException - If thrown by the XML parser
IOException - If thrown by the XML parser
SAXException - If thrown by the XML parser

eval

protected <T> T eval(String expression,
                     Node source,
                     QName returnType)
          throws XPathExpressionException
Evaluate an xpath expression against a DOM Node and return the result.

Parameters:
expression - The expression to evaluate
source - The node against which the expression will be evaluated
returnType - One of the constants defined in XPathConstants
Returns:
The result returned by XPath.evaluate(String, Object, QName)
Throws:
XPathExpressionException - If the xpath expression is invalid

getFilterUrlPatterns

protected List<String> getFilterUrlPatterns(Node filterNode)
                                     throws XPathExpressionException
Get all the URL patterns to which a filter is mapped in web.xml. This includes direct mappings using filter-mapping/url-pattern and indirect mappings using filter-mapping/servlet-name and servlet-mapping/url-pattern.

Parameters:
filterNode - The DOM (&lt;filter&gt;) Node containing the filter declaration from web.xml
Returns:
A list of all the patterns to which the filter is mapped
Throws:
XPathExpressionException - In case of failure evaluating an xpath expression

getFilterParameters

protected Map<String,String> getFilterParameters(Node filterNode)
                                          throws XPathExpressionException
Get the initialization parameters for a filter declared in web.xml.

Parameters:
filterNode - The DOM (&lt;filter&gt;) Node containing the filter declaration from web.xml
Returns:
A map of parameter names to parameter values
Throws:
XPathExpressionException - In case of failure evaluation an xpath expression

createStripesFilter

protected void createStripesFilter(FilterConfig config)
                            throws ServletException
Create and initialize an instance of StripesFilter with the given configuration.

Parameters:
config - The filter configuration
Throws:
ServletException - If initialization of the filter fails

issueRequests

protected void issueRequests(List<String> patterns,
                             HttpServletRequest request,
                             HttpServletResponse response)
Issue a series of requests in an attempt to force an invocation (and initialization) of StripesFilter in the application context. All patterns will be requested first with an internal forward, then an include and finally with a brand new request to the address and port returned by ServletRequest.getLocalAddr() and ServletRequest.getLocalPort(), respectively.

Parameters:
patterns - The list of patterns to request, as specified by url-pattern elements in web.xml
request - The current request, required to process a forward or include
response - The current response, required to process a forward or include

requestRemotely

public void requestRemotely(HttpServletRequest request,
                            String relativePath)
Issue a new request to a path relative to the request's context. The connection is made to the address and port returned by ServletRequest.getLocalAddr() and ServletRequest.getLocalPort(), respectively.

Parameters:
request - The current request
relativePath - The context-relative path to request


© Copyright 2005-2006, Stripes Development Team.