As well as supporting application-wide interceptors, also allows action bean-specific interceptors. Application-wide interceptors are executed before or after requests to each action bean defined in the Struts module concerned, while action bean-specific interceptors are only executed for the action declaring the interceptors.
Action bean-specific interceptors are declared using interceptor annotations. Two interceptor annotations are currently supported.
@BeforeInterceptors
: used to identify BeforeInterceptor
instances whose beforeExecute()
method should be executed before any of the action bean interface methods are invoked.@AfterInterceptors
: used to identify AfterInterceptor
instances whose afterExecute()
method should be executed after all of the action bean interface methods are invoked.An example is shown below:
@BeforeInterceptors(classes={CustomBeforeInterceptor1.class, CustomBeforeInterceptor2.class}) @AfterInterceptors(classes={CustomAfterInterceptor1.class, CustomAfterInterceptor2.class}) public class ExampleInterceptorAction implements BasicAction { private String message; public void setMessage(String message) { this.message = message; } public String execute() { return "success"; } public String getCurrentMessage() { return message; } public String getMessage() { return "Interceptor built message: " + message; } }
CustomBeforeInterceptor1
and CustomBeforeInterceptor2
are executed before the action bean's
execute()
method is invoked.
In the same way, CustomAfterInterceptor1
and
CustomAfterInterceptor2
are executed afterwards.
One useful feature of action bean interceptors is that they can be parameterised using
generics. Consider our implementation of CustomBeforeInterceptor1
.
public class CustomBeforeInterceptor1 implements BeforeInterceptor<ExampleInterceptorAction> { public void beforeExecute(ExampleInterceptorAction action, ActionContext context) { action.setMessage("CustomBeforeInterceptor1,"); } }
CustomBeforeInterceptor1
is parameterised using the
action bean class type ExampleInterceptorAction
.
Without this capability, type casting would be necessary in the application code, as shown in the
next example, which is not parameterized by the action bean type.
public class CustomBeforeInterceptor2 implements BeforeInterceptor { public void beforeExecute(Object actionBean, ActionContext context) { if (actionBean instanceof ExampleInterceptorAction) { ExampleInterceptorAction action = (ExampleInterceptorAction) actionBean; action.setMessage(action.getCurrentMessage()+"CustomBeforeInterceptor2,"); } } }
Strecks will generate an intelligent runtime error message if you attempt to use an interceptor parameterised with a type incompatible with the action bean. Obviously it does not make sense to do this for application-wide interceptors.
This annotation is used to identify the interceptor implementation classes. This annotation
has a single required attribute, classes
, which can either be a single
Class
instance or a
Class
array literal. Note that if application-wide
BeforeInterceptors
have been defined for the
action, these will be executed before any of the
interceptors declared using the @BeforeInterceptors
annotation.
This annotation is used to identify the interceptor implementation classes.
As with @BeforeInterceptors
,
this annotation has a single required attribute, classes
,
which can either be a single Class
instance or a
Class
array literal. If application-wide AfterInterceptors
have been defined for the
action, these will be executed after any of the interceptors declared using the @AfterInterceptors
annotation.