The InvocationContext
interface is used to support information handling within and between interceptors. It is passed as the single argument to a method annotated with the @AroundInvoke annotation. It possesses several methods which can assist in the handling of interceptors. In this recipe we will focus on those methods which provide access to the target method's parameter list and use them to manipulate the parameters.
The basic approach for using an interceptor to validate a target method's parameters involves:
getParameters
method setParameters
method to apply any changes to the parameters proceed
methodTo keep the example simple, we will perform a simple validation. We will call the RegistrationManager's register
method and make sure the parameters do not have any leading or trailing blanks.
First, add a new interceptor to the packt
package called ValidationInterceptor
. Call its method validateParameters
as shown below. In this method we use the println
method to display the execution sequence of the interceptor and the parameters as they are modified.
public class ValidationInterceptor {
@AroundInvoke
public Object validateParameters(InvocationContext context) throws Exception{
System.out.println("ValidationInterceptor");
Object parameters[] = context.getParameters();
for(int i=0; i<parameters.length; i++) {
System.out.println("Before: ["+(String)parameters[i] + "]");
parameters[i] = ((String)parameters[i]).trim();
System.out.println("After: ["+(String)parameters[i]+"]");
}
context.setParameters(parameters);
Object result = context.proceed();
return result;
}
}
Next, precede the RegistrationManager's register
method with the interceptor annotation.
@Interceptors(ValidationInterceptor.class)
In addition, change the output of the RegistrationServlet
to create an attendee that has a combination of leading and trailing blanks for its arguments.
Attendee attendee = registrationManager.register(" Bill Schroder ", "Manager", "Acme Software"); out.println("<h3>" + attendee.getName() + " has been registered</h3>");
Execute the servlet and examine the console output. Depending on the interceptors in place, your output should be similar to the following:
INFO: ValidationInterceptor
INFO: Before: [ Bill Schroder ]
INFO: After: [Bill Schroder]
INFO: Before: [Manager ]
INFO: After: [Manager]
INFO: Before: [ Acme Software]
INFO: After: [Acme Software]
When the interceptor is first executed we used the getParameters
method to retrieve the parameters passed to the target method. The String
method trim
was used to remove any leading or trailing blanks for each parameter. The setParameters
method was then used to pass these new values to the target method. The target method was then invoked with the proceed
method. Additional println
methods have be included to help illustrate the execution sequence.
The InvocationContext
interface provides information about the state of a chain of interceptors and the target. During the execution of this invocation chain, it can be useful to maintain state information. The InvocationContext
interface has seven methods useful for this purpose as listed in the following table. The interceptor has complete access to the target method's name and its parameters.
Method |
Return Value |
Description |
---|---|---|
|
|
The |
|
|
The object represents the method for which the interceptor was executed |
|
|
The array represents the arguments passed to the method |
|
|
A reference to the target |
|
|
A reference to the |
|
|
Control is passed to the next interceptor in the chain or the business method if there are no more interceptors. The return value comes from the next method in the interceptor chain |
|
|
It is passed an array of objects which will be passed to the target's method |
The InvocationContext
interface has a number of other useful methods. The getContextData
method is used to pass information between interceptors. This is illustrated in the Using interceptors to handle application statistics recipe.
Here we will examine two other methods:
getTarget
to return information about the target getMethod
to return information about the target's methodThe getTarget
method returns a reference to the target. Add this statement to the beginning of the validateParameters
method. It returns a reference to the RegistrationManager
.
System.out.println("ValidationInterceptor"); System.out.println(context.getTarget());
One possible output appears as follows:
INFO: ValidationInterceptor
INFO: packt._RegistrationManager_Serializable@101b74e
This reference can be used to access fields and methods of the class. For example, to execute a method we could use code similar to the following:
((RegistrationManager)context.getTarget()).methodName();
The getMethod
returns a java.lang.reflect.Method
object which is useful if you need more detailed information about the method such as the annotations used, exceptions thrown, and parameter types to mention a few.
For example, to determine which annotations are used with the target method, insert the following code at the beginning of the validateParameters
method. The getAnnotations
method returns an array of annotations used with the method. Using a for
each statement and println
method we can display this list.
System.out.println("ValidationInterceptor"); Annotation annotations[] = context.getMethod().getAnnotations(); for(Annotation annotation: annotations) { System.out.println(annotation); }
The output below shows only one annotation being used at this time.
INFO: ValidationInterceptor
INFO: @javax.interceptor.Interceptors(value=[class packt.ValidationInterceptor])
See the Reflection API (java.lang.reflect) to further explore the capabilities of the Method
class.
3.137.223.10