Using deployment descriptors for interceptors

To specify interceptor methods of an interceptor class, we use the<interceptors> element with other elements in the ejb-jar.xml file. In this recipe, we examine how this is done. Interceptors are discussed in more detail in Chapter 8,

Java EE 6 application no longer requires deployment descriptors as annotations have largely taken their place. However, there are certain situations where they are still needed. One of these situations is when we want to use a default interceptor as detailed in the Using deployment descriptors for default interceptors recipe.

Getting ready

The steps to use deployment descriptors include:

  1. Adding an ejb-jar.xml file to your application
  2. Using the<interceptors> element to define interceptors
  3. Using the<interceptor-binding> element to define the interceptor bindings
  4. Deploying the application

    The interceptor bindings defined in the ejb-jar.xml file will override the annotations found in a class. The advantage of using deployment descriptors lies in the ability to control the interceptors without having to modify the EJB source code. This can result in a more portable and malleable application.

How to do it...

To use deployment descriptors for interceptors, you will need to create an ejb-jar.xml file in the EJB module under the META-INF directory. This process is development environment-specific. For example, in NetBeans, right-click on the EJB module for your project in the Project Explorer and select New | Standard Deployment Descriptor. This will create the ejb-jar.xml file.

Consider the SimpleInterceptor class defined in Chapter 8, Defining and Using Interceptor recipe.

public class SimpleInterceptor {
@AroundInvoke
public Object simpleMethod(InvocationContext context) throws Exception{
...
}
}

Using the @Interceptors annotation as shown below will result in all methods of the RegistrationManager class being intercepted and handled by SimpleInterceptor.

@Stateful
@Interceptors(SimpleInterceptor.class)
public class RegistrationManager {
...
}

We can achieve the same result using the<assembly-binding> element within the<assembly-descriptor> element. First, add an ejb-jar.xml file to your application. Add an<ejb-jar> element as the root element of the file.

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns = "http://java.sun.com/xml/ns/javaee"
version = "3.1"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd">
...
</ejb-jar>

Within the root element, we will add an<interceptors> element followed by an<assembly-descriptor> element. The first element is used to declare an interceptor and the second binds the interceptor to an EJB.

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns = "http://java.sun.com/xml/ns/javaee"
version = "3.1"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd">
<interceptors>
...
</interceptors>
<assembly-descriptor>
...
</assembly-descriptor>
</ejb-jar>

The<interceptor-class> element is nested inside the<interceptor> element. Its value identifies the interceptor class. In this case, it is packt.SimpleInterceptor.

<interceptor>
<interceptor-class>packt.SimpleInterceptor</interceptor-class>
</interceptor>
</interceptors>

The<assembly-descriptor> element contains an<interceptor-binding> element. Within this element, the name of the EJB is declared using an<ejb-name> element and the name of the interceptor class using an<interceptor-class> element. Here the RegistrationManager EJB is associated with the SimpleInterceptor.

<assembly-descriptor>
<interceptor-binding>
<ejb-name>RegistrationManager</ejb-name>
<interceptor-class>packt.SimpleInterceptor</interceptor-class>
</interceptor-binding>
</assembly-descriptor>

To specify the use of an interceptor for all classes, use the asterisk wildcard character.

<interceptor-binding>
<ejb-name>*</ejb-name>
<interceptor-class>packt.SimpleInterceptor</interceptor-class>
</interceptor-binding>

How it works...

The ejb-jar.xml file was used to specify the configuration of the SimpleInterceptor for use with the methods of the RegistrationManager. The<interceptors> element was used to define the interceptor and the<assembly-descriptor> element was used to associate the methods of the RegistrationManager with the interceptor. When the application is deployed, the server will intercept calls to the RegistrationManager's methods using the SimpleInterceptor. This technique provides a way of allowing the deployer to determine when the interceptor should be used without having to use annotations.

There's more...

Interceptors can be bound to:

  • All target classes. These are called default interceptors and are covered in Using deployment descriptors for default interceptors recipe
  • One target class (class-level interceptors)
  • Methods of a class (method-level interceptors)

In the previous section, the use of class-level interceptors was illustrated. In addition, we can exclude interceptors for classes and/or methods. We can also control the execution order of interceptors using deployment descriptors.

Using method-level interceptor descriptors

To restrict the use of the interceptor to a specific method of a class, use the<method-name> element in conjunction with the<method> element. If the method is overloaded, the interceptor is applied to all of the methods. In the following example, we associate the SimpleInterceptor with the RegistrationManager's register method.

...
<interceptor-binding>
<ejb-name>RegistrationManager</ejb-name>
<interceptor-class>packt.SimpleInterceptor</interceptor-class>
<method>
<method-name>register</method-name>
</method>
</interceptor-binding>

If we need to identify a specific overloaded method, then we use one or more<method-params> elements inside of the<method-params> element. These immediately follow the<method-name> element. The<method-param> element contains the data type of the parameter.

While the register method is not overloaded, the following illustrates the use of these elements. This matches a register method with three string parameters.

<interceptor-binding>
<ejb-name>RegistrationManager</ejb-name>
<interceptor-class>packt.SimpleInterceptor</interceptor-class>
<method>
<method-name>register</method-name>
<method-params>
<method-param>java.lang.String</method-param>
<method-param>java.lang.String</method-param>
<method-param>java.lang.String</method-param>
</method-params>
</method>
</interceptor-binding>

If the parameter data type is void, then the element is left empty.

<method-param></method-param>

Excluding interceptors

Interceptors can be assigned at the class level. They will apply to all methods of the class. However, if you wish to exclude an interceptor for a specific method, you can use the @ExcludeClassInterceptors annotation or use the<exclude-class-interceptors> element in the deployment descriptor.

To demonstrate the use of the deployment descriptor approach, use the @Interceptors annotation with the RegistrationManager class.

@Interceptors(SimpleInterceptor.class)
public class RegistrationManager {

Next, modify the ejb-jar.xml file to use the<exclude-class-interceptors> element. The element uses a true or false value to exclude or include the class-level interceptors. The following illustrates how to exclude the use of any class-level interceptors for the RegistrationManager's register method:

<interceptor-binding>
<ejb-name>RegistrationManager</ejb-name>
<exclude-class-interceptors>true</exclude-class-interceptors>
<method>
<method-name>register</method-name>
</method>
</interceptor-binding>

Default interceptors can also be excluded from a method using the<exclude-default-interceptors> element. It works in the same way as the<exclude-class-interceptors> element and is illustrated here:

<interceptor-binding>
<ejb-name>RegistrationManager</ejb-name>
<exclude-default-interceptors>true</exclude-default-interceptors>
<exclude-class-interceptors>true</exclude-class-interceptors>
<method>
<method-name>register</method-name>
</method>
</interceptor-binding>

Controlling the execution order of interceptors

Interceptors are normally executed in the order they are declared in an annotation. However, the order can be controlled in a deployment descriptor using the<interceptor-order> element. Within this element the<interceptor-class> element specifies the interceptors to use and their order. They are executed in the order they are listed. The following illustrates this technique for the register method where the SimpleInterceptor is executed before the DefaultInterceptor:

<interceptor-binding>
<ejb-name>RegistrationManager</ejb-name>
<interceptor-order>
<interceptor-class>packt.SimpleInterceptor</interceptor-class>
<interceptor-class>packt.DefaultInterceptor</interceptor-class>
</interceptor-order>
<method>
<method-name>register</method-name>
</method>
</interceptor-binding>

See also

Timer interceptors are discussed in the Using deployment descriptors for timer interceptors recipe and callback interceptors are detailed in the Using deployment descriptors for callback interceptors recipe.

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

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