From: markt Date: Tue, 19 Oct 2010 19:52:28 +0000 (+0000) Subject: Re-factor ServletRequestListener events with an eye to https://issues.apache.org... X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=2005500963ea1aa660a624e15289656f0ea76288;p=tomcat7.0 Re-factor ServletRequestListener events with an eye to https://issues.apache.org/bugzilla/show_bug.cgi?id=49991 and any possible future changes in the Servlet spec git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1024381 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/java/org/apache/catalina/Context.java b/java/org/apache/catalina/Context.java index 95d7e1b3a..7ba544821 100644 --- a/java/org/apache/catalina/Context.java +++ b/java/org/apache/catalina/Context.java @@ -24,6 +24,7 @@ import java.util.Set; import javax.servlet.ServletContainerInitializer; import javax.servlet.ServletContext; +import javax.servlet.ServletRequest; import javax.servlet.ServletSecurityElement; import javax.servlet.descriptor.JspConfigDescriptor; @@ -1005,6 +1006,20 @@ public interface Context extends Container { /** + * Notify all {@link ServletRequestListener}s that a request has started. + * @return true if the listeners fire successfully, else + * false + */ + public boolean fireRequestInitEvent(ServletRequest request); + + /** + * Notify all {@link ServletRequestListener}s that a request has ended. + * @return true if the listeners fire successfully, else + * false + */ + public boolean fireRequestDestroyEvent(ServletRequest request); + + /** * Reload this web application, if reloading is supported. * * @exception IllegalStateException if the reloadable diff --git a/java/org/apache/catalina/core/StandardContext.java b/java/org/apache/catalina/core/StandardContext.java index d5006fb38..27982c7a9 100644 --- a/java/org/apache/catalina/core/StandardContext.java +++ b/java/org/apache/catalina/core/StandardContext.java @@ -48,6 +48,7 @@ import javax.management.NotificationListener; import javax.management.ObjectName; import javax.naming.NamingException; import javax.naming.directory.DirContext; +import javax.servlet.DispatcherType; import javax.servlet.FilterConfig; import javax.servlet.Servlet; import javax.servlet.ServletContainerInitializer; @@ -57,7 +58,9 @@ import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.ServletException; import javax.servlet.ServletRegistration; +import javax.servlet.ServletRequest; import javax.servlet.ServletRequestAttributeListener; +import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener; import javax.servlet.ServletSecurityElement; import javax.servlet.descriptor.JspConfigDescriptor; @@ -5503,6 +5506,83 @@ public class StandardContext extends ContainerBase return hostName; } + + @Override + public boolean fireRequestInitEvent(ServletRequest request) { + + Object instances[] = getApplicationEventListeners(); + + if ((instances != null) && (instances.length > 0)) { + + ServletRequestEvent event = + new ServletRequestEvent(getServletContext(), request); + + for (int i = 0; i < instances.length; i++) { + if (instances[i] == null) + continue; + if (!(instances[i] instanceof ServletRequestListener)) + continue; + ServletRequestListener listener = + (ServletRequestListener) instances[i]; + + try { + // Don't fire the listener for async requests + if (!DispatcherType.ASYNC.equals( + request.getDispatcherType())) { + listener.requestInitialized(event); + } + } catch (Throwable t) { + ExceptionUtils.handleThrowable(t); + getLogger().error(sm.getString( + "standardContext.requestListener.requestInit", + instances[i].getClass().getName()), t); + request.setAttribute(Globals.EXCEPTION_ATTR,t); + return false; + } + } + } + return true; + } + + + @Override + public boolean fireRequestDestroyEvent(ServletRequest request) { + Object instances[] = getApplicationEventListeners(); + + if ((instances != null) && (instances.length > 0)) { + + ServletRequestEvent event = + new ServletRequestEvent(getServletContext(), request); + + for (int i = 0; i < instances.length; i++) { + int j = (instances.length -1) -i; + if (instances[j] == null) + continue; + if (!(instances[j] instanceof ServletRequestListener)) + continue; + ServletRequestListener listener = + (ServletRequestListener) instances[j]; + + try { + // Don't fire the listener for async requests + if (!DispatcherType.ASYNC.equals( + request.getDispatcherType())) { + listener.requestDestroyed(event); + } + } catch (Throwable t) { + ExceptionUtils.handleThrowable(t); + getLogger().error(sm.getString( + "standardContext.requestListener.requestInit", + instances[j].getClass().getName()), t); + request.setAttribute(Globals.EXCEPTION_ATTR,t); + return false; + } + } + } + return true; + } + + /** * Set the appropriate context attribute for our work directory. */ diff --git a/java/org/apache/catalina/core/StandardContextValve.java b/java/org/apache/catalina/core/StandardContextValve.java index e28a0d18f..f7da0b1b7 100644 --- a/java/org/apache/catalina/core/StandardContextValve.java +++ b/java/org/apache/catalina/core/StandardContextValve.java @@ -166,66 +166,15 @@ final class StandardContextValve } } - // Normal request processing - Object instances[] = context.getApplicationEventListeners(); - - ServletRequestEvent event = null; - - if ((instances != null) && (instances.length > 0)) { - event = new ServletRequestEvent - (((Context) container).getServletContext(), - request.getRequest()); - // create pre-service event - for (int i = 0; i < instances.length; i++) { - if (instances[i] == null) - continue; - if (!(instances[i] instanceof ServletRequestListener)) - continue; - ServletRequestListener listener = - (ServletRequestListener) instances[i]; - try { - if (!request.isAsyncDispatching()) { - listener.requestInitialized(event); - } - } catch (Throwable t) { - ExceptionUtils.handleThrowable(t); - container.getLogger().error(sm.getString( - "standardContext.requestListener.requestInit", - instances[i].getClass().getName()), t); - ServletRequest sreq = request.getRequest(); - sreq.setAttribute(Globals.EXCEPTION_ATTR,t); - return; - } + // If a request init listener throws an exception, the request is + // aborted + if (context.fireRequestInitEvent(request)) { + if (request.isAsyncSupported()) { + request.setAsyncSupported(wrapper.getPipeline().isAsyncSupported()); } - } - if (request.isAsyncSupported()) { - request.setAsyncSupported(wrapper.getPipeline().isAsyncSupported()); - } - wrapper.getPipeline().getFirst().invoke(request, response); + wrapper.getPipeline().getFirst().invoke(request, response); - if ((instances !=null ) && (instances.length > 0)) { - // create post-service event - for (int i = 0; i < instances.length; i++) { - int j = (instances.length -1) -i; - if (instances[j] == null) - continue; - if (!(instances[j] instanceof ServletRequestListener)) - continue; - ServletRequestListener listener = - (ServletRequestListener) instances[j]; - try { - if (!request.isAsyncDispatching()) { - listener.requestDestroyed(event); - } - } catch (Throwable t) { - ExceptionUtils.handleThrowable(t); - container.getLogger().error(sm.getString( - "standardContext.requestListener.requestDestroy", - instances[j].getClass().getName()), t); - ServletRequest sreq = request.getRequest(); - sreq.setAttribute(Globals.EXCEPTION_ATTR,t); - } - } + context.fireRequestDestroyEvent(request); } }