SessionContext
The javax.ejb.SessionContext
interface provides a view into the EJB container's environment. The SessionContext object can be used as the bean instance's interface to the EJB container to obtain information about the context of the method invocation call and to provide quick access to various EJB services. A session bean can obtain a reference to its SessionContext by using the @Resource annotation:
@Stateless
public class ProcessPaymentBean implements ProcessPaymentLocal {
@Resource SessionContext ctx;
...
}
SessionContext allows you to obtain information such as the current user that is invoking on the EJB or to look up entries within the EJB's ENC. Let's look at the javax.ejb.SessionContext
interface:
public interface javax.ejb.SessionContext extends javax.ejb.EJBContext {
EJBLocalObject getEJBLocalObject( ) throws IllegalStateException
EJBObject getEJBObject( ) throws IllegalStateException;
MessageContext getMessageContext( ) throws IllegalStateException;
<T> getBusinessObject(Class<T> businessInterface)
throws IllegalStateException;
Class getInvokedBusinessInterface( );
}
The getEJBObject( ) and getEJBLocalObject( ) methods are obsolete and will throw an exception if invoked on. They are objects that are specific to the EJB 2.1 style of defining EJBs.
The SessionContext.getBusinessObject( )
method returns a reference to the current EJB that can be invoked on by other clients. This reference is the EJB equivalent to Java's this pointer. The businessInterface parameter must be one of the EJB's remote or local interfaces so that the container knows whether to create a remote or local reference to the current EJB. The getBusinessObject( ) method allows the bean instance to get its own EJB object reference, which it can then pass to other beans. Here is an example:
@Stateless
public class A_Bean implements A_BeanRemote {
@Resource private SessionContext context;
public void someMethod( ) {
B_BeanRemote b = ... // Get a remote reference to B_Bean.
A_BeanRemote mySelf = getBusinessObject(A_BeanRemote.class);
b.aMethod( mySelf );
}
...
}
It is illegal for a bean instance to pass a this reference to another bean; instead, it passes its remote or local EJB object reference, which the bean instance gets from its SessionContext.
The SessionContext.getInvokedBusinessInterface( )
method allows you to determine whether your EJB was invoked on through its remote, local, or web service interface. It returns the invoked business interface as a class.
EJBContext
SessionContext extends the javax.ejb.EJBContext
class. EJBContext defines several methods that provide useful information to a bean at runtime.
Here is the definition of the EJBContext interface:
package javax.ejb;
public interface EJBContext {
public Object lookup(String name);
// EJB 2.1 only: TimerService
public TimerService getTimerService( )
throws java.lang.IllegalStateException;
// security methods
public java.security.Principal getCallerPrincipal( );
public boolean isCallerInRole(java.lang.String roleName);
// transaction methods
public javax.transaction.UserTransaction getUserTransaction( )
throws java.lang.IllegalStateException;
public boolean getRollbackOnly( )
throws java.lang.IllegalStateException;
public void setRollbackOnly( )
throws java.lang.IllegalStateException;
// deprecated and obsolete methods
public java.security.Identity getCallerIdentity( );
public boolean isCallerInRole(java.security.Identity role);
public java.util.Properties getEnvironment( );
public EJBHome getEJBHome( )
java.lang.IllegalStateException;
public EJBLocalHome getEJBLocalHome( )
java.lang.IllegalStateException;
}
EJBContext.lookup( ) is a convenience method that allows you to look up entries in the EJB's ENC.
The EJBContext.getTimerService( ) method returns a reference to the container's Timer Service, which allows the stateless bean to set up notifications of timed events for itself. In other words, a session bean can set alarms so that the container will call it when a specific date arrives or some interval of time has passed. The Timer Service can also be injected using the @Resource annotation. The Timer Service is covered in detail in Chapter 13.
The EJBContext.getCallerPrincipal( ) method is used to obtain the java.security.Principal
object representing the client that is currently accessing the bean. The Principal object can, for example, be used by an EJB to track the identities of clients making updates:
@Stateless
public class BankBean implements Bank {
@Resource SessionContext context;
...
public void withdraw(int acctid, double amount) throws AccessDeniedException {
String modifiedBy = principal.getName( );
...
}
...
}
The EJBContext.isCallerInRole( ) method tells you whether the client accessing the bean is a member of a specific role, identified by a role name. This method is useful when more access control is needed than simple method-based access control can provide. In a banking system, for example, you might allow the Teller
role to make most withdrawals but only the Manager
role to make withdrawals of more than $10,000. This kind of fine-grained access control cannot be addressed through EJB's security attributes, because it involves a business logic problem. Therefore, we can use the isCallerInRole( ) method to augment the automatic access control provided by EJB. First, let's assume that all managers are also tellers. The business logic in the withdraw( ) method uses isCallerInRole( ) to make sure that only the Manager role can withdraw sums of more than $10,000:
@Stateless
public class BankBean implements Bank {
@Resource SessionContext context;
public void withdraw(int acctid, double amount) throws AccessDeniedException {
if (amount > 10000) {
boolean isManager = context.isCallerInRole("Manager");
if (!isManager) {
// Only Managers can withdraw more than 10k.
throw new AccessDeniedException( );
}
}
}
...
}
The transactional methodsgetUserTransaction( ), setRollbackOnly( ), and geTRollbackOnly( )are described in detail in Chapter 16.
EJBContext contains some methods that were used in older EJB specifications but have been abandoned in EJB 3.0. The security methods that interact with Identity
classes, as well as the getEnvironment( ), EJBContext.getEJBHome( ), and EJBContext.getEJBLocalHome( ) methods, are now obsolete. A RuntimeException
is thrown if these methods are executed.
The material on EJBContext covered in this section applies equally well to message-driven beans. There are some exceptions, however, and these differences are covered in Chapter 12.
 |