Most web applications require operations which are common to many actions, such logging, authentication and customized state management. In Struts 1.2 it is relatively difficult to accomodate these requirements in an elegant way. A Struts developer typically has two choices:
RequestProcessor
subclassAction
superclass which all of the application's actions should extendStrecks uses interceptors to solves meet these requirements.
Strecks defines two interceptor interfaces, BeforeInterceptor
, and AfterInterceptor
.
A class which provides a simple implementation of both is shown below:
public class ActionLoggingInterceptor implements BeforeInterceptor, AfterInterceptor { private static Log log = LogFactory.getLog(ActionLoggingInterceptor.class); public void beforeExecute(Object actionBean, ActionContext context) { HttpServletRequest request = context.getRequest(); log.info("Starting process action perform " + request.getRequestURI()); log.info("Using " + context.getMapping().getType()); } public void afterExecute(Object actionBean, ActionContext context, Exception e) { HttpServletRequest request = context.getRequest(); log.info("Ended action perform of " + request.getRequestURI() + StringUtils.LINE_SEPARATOR); } }
The life cycle of interceptor invocation is controlled in the implementation of
the Strecks ControllerProcessorDelegate
, which is used to per-request action execution.
The behaviour described next
is present in the default implementation, ControllerProcessorDelegateImpl
.
Interceptors have access to the ActionContext
and the same injected state as the action bean itself.
BeforeInterceptors
are run before any of the action bean methods execute but after
action bean dependency injection has occurred.
Neither BeforeInterceptors
nor AfterInterceptor
can affect navigation -
this is the responsibility of the action bean and controller.
BeforeInterceptors
can interrupt action execution by throwing an exception.
In this case, the neither the action bean methods nor the beforeExecute()
method of remaining BeforeInterceptors
will be executed.
By contrast, the afterExecute()
of each AfterInterceptor
is always executed.
If an exception
has been thrown during execution, this will be passed in to the afterExecute()
method.
Interceptors can either be application-wide, which means that they operate across all actions in a given Struts module, or action bean-specific which means that it will only execute before or after the interface methods of instances of the action bean concerned.
Application-wide interceptors are specified using interceptor configuration, while Action bean-specific interceptors are set up using interceptor annotations.