Using the InvocationContext to verify parameters

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.

Getting ready

The basic approach for using an interceptor to validate a target method's parameters involves:

  1. Accessing the target's parameters using the getParameters method
  2. Validating and possibly modifying the parameters
  3. Using the setParameters method to apply any changes to the parameters
  4. Invoking the proceed method

How to do it...

To 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]

How it works...

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

getContextData

java.util.Map

The Map containing the context data.

getMethod

java.lang.reflect.Method

The object represents the method for which the interceptor was executed

getParameters

Objects[]

The array represents the arguments passed to the method

getTarget

Object

A reference to the target

getTimer

Object

A reference to the Timer object for the target if present

proceed

Object

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

setParameters

void

It is passed an array of objects which will be passed to the target's method

There's more...

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:

  • Using getTarget to return information about the target
  • Using getMethod to return information about the target's method

Using getTarget to return information about the target

The 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();

Using getMethod to return information about the target's method

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.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.223.10