Ok, here is exactly what we use here at Magnet. Please ignore the 1.0-ness. Also excuse the scarcity of Javadocs for the individual methods.. hopefully the stuff at the head of the class explains it.
package com.magnetbanking.util.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.magnetbanking.util.logging.Loggers; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import java.util.*; /** * * <p>This servlet allows custom code to be inserted into various places in * the Struts request processing cycle. The custom classes are specified * by the init-parameters in web.xml and must implement the interfaces * described in the following table.</p> * * <p>All custom functionality that was once directly embedded in this * class has been factored out into processing classed that can be * plugged in here.</p> * * <table border="1"> * <tr> * <th>init-param</th> * <th>interface</th> * <th>description</th> * </td> * <tr> * <td>preProcessor</td> * <td>com.magnetbanking.util.servlet.PreProcessor</td> * <td>This will be called within the processPreProcess method. * The process method's return code has the same semantics as * the processPreProcess mehtod itself - if false is returned, * no further process will take place. * </td> * </tr> * <tr> * <td>mappingProcessor</td> * <td>com.magnetbanking.util.servlet.MappingProcessor</td> * <td>This will be called as soon as the request path has been resolved * into an ActionMapping. If the <code>process</code> method returns * true, everything will proceed normally. If it returns false, the * servlet will behave as if no action mapping could be found for the * path specified. This is ideal for security checking, since it is done * before any Action or ActionForm instances are created, so if anything * strange is detected, the request can be stopped as soon as possible. * The disadvantage is that we don't have access to the ActionForm * or to the response object. * </td> * </tr> * <tr> * <td>actionPreProcessor</td> * <td>com.magnetbanking.util.servlet.ActionProcessor</td> * <td>The <code>process</code> method will be called immediately before * the Action instance's <code>perform</code> method. If the process * method returns false, the action will not be performed. * </td> * </tr> * <tr> * <td>actionPostProcessor</td> * <td>com.magnetbanking.util.servlet.ActionProcessor</td> * <td>The <code>process</code> method will be called immediately <b>after</b> * the Action instance's <code>perform</code> method. * </td> * </tr> * </table> * <p> * If multiple classnames (separated by whitespace) are provided for any of the * above parameters, the classes will be called in the order in which they are * listed. There is a "logical AND" short-circuit behavior: if any processor * returns false from its process method, the following ones will not be called. * * @author Jeff Robertson * @author Scott Alexander Long * @version $Revision: 1.68.2.4 $ $Date: 2001/10/07 04:49:15 $ */ public class FilteringActionServlet extends org.apache.struts.action.ActionServlet { protected Collection preProcs = new ArrayList(1); protected Collection mappingProcs = new ArrayList(1); protected Collection actionPreProcs = new ArrayList(1); protected Collection actionPostProcs = new ArrayList(1); protected void initMapping() throws IOException, ServletException { super.initMapping(); initProcessors(); } protected void initProcessors() throws IOException, ServletException { initProcessors(this.preProcs, getServletConfig().getInitParameter("preProcessor")); initProcessors(this.mappingProcs, getServletConfig().getInitParameter("mappingProcessor")); initProcessors(this.actionPreProcs, getServletConfig().getInitParameter("actionPreProcessor")); initProcessors(this.actionPostProcs, getServletConfig().getInitParameter("actionPostProcessor")); } private void initProcessors(Collection procs, String s) { if( s == null || s.trim().length() == 0 ) { return; } for( StringTokenizer st = new StringTokenizer(s); st.hasMoreTokens(); ) { String procClass = st.nextToken().trim(); try { ProcessorConfig current = (ProcessorConfig) Class.forName(procClass).newInstance(); current.init(this); procs.add( current ); } catch (Exception e) { Loggers.util.servlet.error("Unable to instantiate processor " + procClass, e); } } } protected ActionMapping processMapping(String path, HttpServletRequest request) { ActionMapping mapping = super.processMapping(path, request); for( Iterator i = this.mappingProcs.iterator(); i.hasNext();) { MappingProcessor mp = (MappingProcessor) i.next(); if( ! mp.processMapping(mapping, request)) { return null; } } return mapping; } protected boolean processPreprocess(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { for( Iterator i = this.preProcs.iterator(); i.hasNext();) { PreProcessor p = (PreProcessor) i.next(); if( ! p.process(request,response)) { return false; } } return true; } protected ActionForward processActionPerform(Action action, ActionMapping mapping, ActionForm formInstance, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { for( Iterator i = this.actionPreProcs.iterator(); i.hasNext();) { ActionProcessor ap = (ActionProcessor) i.next(); if( ! ap.process(action,mapping, formInstance, request, response)) { return null; } } ActionForward forward = super.processActionPerform(action, mapping, formInstance, request, response); for( Iterator i = this.actionPreProcs.iterator(); i.hasNext();) { ActionProcessor ap = (ActionProcessor) i.next(); if( ! ap.process(action,mapping, formInstance, request, response)) { return forward; } } return (forward); } } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]