Stripes includes an Interceptor system designed to make it easy to add functionality to Stripes. For cross-cutting behaviour it is often simpler to write an interceptor than to extend Stripes' built in components.
The following classes form the core of the Stripes lifecycle and interceptor system:
...
Let's look at an example. The following is a simply interceptor that "logs" a message before and after every lifecycle stage:
Code Block | ||||
---|---|---|---|---|
| ||||
@Intercepts({LifecycleStage.ActionBeanResolution, LifecycleStage.HandlerResolution, LifecycleStage.BindingAndValidation, LifecycleStage.CustomValidation, LifecycleStage.EventHandling, LifecycleStage.ResolutionExecution}) public class NoisyInterceptor implements Interceptor { public Resolution intercept(ExecutionContext ctx) throws Exception { System.out.println("Before " + ctx.getLifecycleStage()); Resolution resolution = ctx.proceed(); System.out.println("After " + ctx.getLifecycleStage()); return resolution } } |
...
Configuring interceptors is fairly straightforward. With Stripes 1.5 and up, your interceptors will automatically be detected if they are in a package configured with the Extension.Packages
parameter. You can also use an initialization parameter of the Stripes Filter:
Code Block | ||||
---|---|---|---|---|
| ||||
<init-param> <param-name>Interceptor.Classes</param-name> <param-value> com.myco.NoisyInterceptor </param-value> </init-param> </filter> |
...
If you are using Stripes 1.4.x or earlier, you must use the web.xml configuration, and the only gotcha is that Stripes by default configures a single interceptor, the BeforeAfterMethodInterceptor. When specifying interceptors you need to also specify the BeforeAfterMethodInterceptor
unless you wish to disable it:
Code Block | ||||
---|---|---|---|---|
| ||||
<init-param> <param-name>Interceptor.Classes</param-name> <param-value> com.myco.NoisyInterceptor, net.sourceforge.stripes.controller.BeforeAfterMethodInterceptor </param-value> </init-param> </filter> |
...
Another example of where an interceptor might be useful is in application security. A prototype interceptor might look like:
Code Block | ||||
---|---|---|---|---|
| ||||
@Intercepts(LifecycleStage.HandlerResolution) public class SecurityInterceptor implements Interceptor { /** Intercepts execution and checks that the user has appropriate permissions. */ public Resolution intercept(ExecutionContext ctx) throws Exception { Resolution resolution = ctx.proceed(); if (isPermitted(ctx.getActionBean(), ctx.getActionBeanContext()) { return resolution; } else if (loggedIn(ctx.getActionBeanContext()) { return new RedirectResolution("/security/Unauthorized.jsp"); } else { return new RedirectResolution("/security/Login.jsp"); } } /** Returns true if the user is logged in. */ protected boolean isLoggedIn(ActionBeanContext ctx) { return ((MyActionBeanContext) ctx).getUser() != null; } /** Returns true if the user is permitted to invoke the event requested. */ protected boolean isPermitted() { ... } } |
...