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.
The steps to use deployment descriptors include:
ejb-jar.xml
file to your application<interceptors>
element to define interceptors<interceptor-binding>
element to define the interceptor bindingsThe 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.
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>
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.
Interceptors can be bound to:
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.
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>
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>
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>
3.136.17.12