Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

EJB 3.1: Introduction to Interceptors

Save for later
  • 7 min read
  • 06 Jul 2011

article-image

EJB 3.1 Cookbook


ejb-31-introduction-interceptors-img-0

Build real world EJB solutions with a collection of simple but incredibly effective recipes with this book and eBook

Introduction


Most applications have cross-cutting functions which must be performed. These cross-cutting functions may include logging, managing transactions, security, and other aspects of an application. Interceptors provide a way to achieve these cross-cutting activities.

The use of interceptors provides a way of adding functionality to a business method without modifying the business method itself. The added functionality is not intermeshed with the business logic resulting in a cleaner and easier to maintain application.

Aspect Oriented Programming (AOP) is concerned with providing support for these cross-cutting functions in a transparent fashion. While interceptors do not provide as much support as other AOP languages, they do offer a good level of support.

Interceptors can be:

  • Used to keep business logic separate from non-business related activities
  • Easily enabled/disabled
  • Provide consistent behavior across an application


Interceptors are specific methods invoked around a method or methods of a target EJB. We will use the term target, to refer to the class containing the method(s) an interceptor will be executing around.

The interceptor's method will be executed before the EJB's method is executed. When the interceptor method executes, it is passed as an InvocationContext object. This object provides information relating to the state of the interceptor and the target. Within the interceptor method, the InvocationContext's method proceed can be issued that will result in the target's business method being executed or, as we will see shortly, the next interceptor in the chain. When the business method returns, the interceptor continues execution. This permits execution of code before and after the execution of a business method.

Interceptors can be used with:

  • Stateless session EJBs
  • Stateful session EJBs
  • Singleton session EJBs
  • Message-driven beans


The @Interceptors annotation defines which interceptors will be executed for all or individual methods of a class. Interceptor classes use the same lifecycle of the EJB they are applied to, in the case of stateful EJBs, which means the interceptor could be passivated and activated. In addition, they support the use of dependency injection. The injection is done using the EJB's naming context.

More than one interceptor can be used at a time. The sequence of interceptor execution is referred to as an interceptor chain. For example, an application may need to start a transaction based on the privileges of a user. These actions should also be logged. An interceptor can be defined for each of these activities: validating the user, starting the transaction, and logging the event. The use of interceptor chaining is illustrated in the Using interceptors to handle application statistics recipe.

Lifecycle callbacks such as @PreDestroy and @PostConstruct can also be used within interceptors. They can access interceptor state information as discussed in the Using lifecycle methods in interceptors recipe.

Interceptors are useful for:

  • Validating parameters and potentially changing them before they are sent to a method
  • Performing security checks
  • Performing logging
  • Performing profiling
  • Gathering statistics


An example of parameter validation can be found in the Using the InvocationContext to verify parameters recipe. Security checks are illustrated in the Using interceptors to enforce security recipe. The use of interceptor chaining to record a method's hit count and the time spent in the method is discussed in the Using interceptors to handle application statistics recipe. Interceptors can also be used in conjunction with timer services.

The recipes in this article are based largely around a conference registration application as developed in the first recipe. It will be necessary to create this application before the other recipes can be demonstrated.

Creating the Registration Application


A RegistrationApplication is developed in this recipe. It provides the ability of attendees to register for a conference. The application will record their personal information using an entity and other supporting EJBs. This recipe details how to create this application.

Getting ready


The RegistrationApplication consists of the following classes:

  • Attendee – An entity representing a person attending the conference
  • AbstractFacade – A facade-based class
  • AttendeeFacade – The facade class for the Attendee class
  • RegistrationManager – Used to control the registration process
  • Unlock access to the largest independent learning library in Tech for FREE!
    Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
    Renews at ₹800/month. Cancel anytime
  • RegistrationServlet – The GUI interface for the application


The steps used to create this application include:

  1. Creating the Attendee entity and its supporting classes
  2. Creating a RegistrationManager EJB to control the registration process
  3. Creating a RegistrationServlet to drive the application


The RegistrationManager will be the primary vehicle for the demonstration of interceptors.

How to do it...


Create a Java EE application called RegistrationApplication. Add a packt package to the EJB module and a servlet package in the application's WAR module.

Next, add an Attendee entity to the packt package. This entity possesses four fields: name, title, company, and id. The id field should be auto generated. Add getters and setters for the fields. Also add a default constructor and a three argument constructor for the first three fields. The major components of the class are shown below without the getters and setters.

@Entity
public class Attendee implements Serializable {
private String name;
private String title;
private String company;
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;


public Attendee() {
}

public Attendee(String name, String title, String company) {
this.name = name;
this.title = title;
this.company = company;
}
}



Next, add an AttendeeFacade stateless session bean which is derived from the AbstractFacade class. The AbstractFacade class is not shown here.

@Stateless
public class AttendeeFacade extends AbstractFacade<Attendee> {
@PersistenceContext(unitName = "RegistrationApplication-ejbPU")
private EntityManager em;


protected EntityManager getEntityManager() {
return em;
}

public AttendeeFacade() {
super(Attendee.class);
}
}



Add a RegistrationManager stateful session bean to the packt package. Add a single method, register, to the class. The method should be passed three strings for the name, title, and company of the attendee. It should return an Attendee reference. Use dependency injection to add a reference to the AttendeeFacade. In the register method, create a new Attendee and then use the AttendeeFacade class to create it. Next, return a reference to the Attendee.

@Stateful
public class RegistrationManager {


@EJB
AttendeeFacade attendeeFacade;

Attendee attendee;

public Attendee register(String name, String title,
String company) {
attendee = new Attendee(name, title, company);
attendeeFacade.create(attendee);
return attendee;
}
}



In the servlet package of the WAR module, add a servlet called RegistrationServlet. Use dependency injection to add a reference to the RegistrationManager. In the try block of the processRequest method, use the register method to register an attendee and then display the attendee's name.

public class RegistrationServlet extends HttpServlet {
@EJB
RegistrationManager registrationManager;


protected void processRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();

try {

out.println("<html>");
out.println("<head>");
out.println("<title>Servlet RegistrationServlet</title>");
out.println("</head>");
out.println("<body>");
Attendee attendee = registrationManager.register("Bill
Schroder", "Manager", "Acme Software");
out.println("<h3>" + attendee.getName() + " has been
registered</h3>");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
}
...
}



Execute the servlet. The output should appear as shown in the following screenshot:

ejb-31-introduction-interceptors-img-1


How it works...


The Attendee entity holds the registration information for each participant. The RegistrationManager session bean only has a single method at this time. In later recipes we will augment this class to add other capabilities. The RegistrationServlet is the client for the EJBs.