ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

An Exception Handling Framework for J2EE Applications
Pages: 1, 2, 3, 4, 5, 6

Checked Exceptions

  • Business exceptions: Exceptions that occur while performing business logic. BaseBusinessException is the base class for this category.
  • DB exceptions: Exceptions thrown while interacting with persistence mechanism. BaseDBException is the base class for this category.
  • Security exceptions: The exceptions that come while performing security operations. The base class for this type of exceptions will be BaseSecurityException.
  • Confirmation exceptions: Used for getting a confirmation from the end user for executing a specific task. The base class for this category is BaseConfirmationException.

Unchecked Exceptions

  • System exception: There are times when you would like to use unchecked exceptions. For instance, you may not want to handle exceptions coming from third-party library APIs. Rather, you would like to wrap them in unchecked exceptions and throw to the controller. At times, there are configuration issues, which again cannot be handled by the client and should be raised as unchecked exceptions. All custom unchecked exceptions should extend from the java.lang.RuntimeException class.

Presentation-Level Exception Handling

The presentation layer is uniquely responsible for deciding the action to be taken for an exception. That decision-making involves identifying the error code based on the exception thrown. Also, we need to know to which screen we should redirect after handling the error.



We need an abstraction for getting the error code based on the type of exception. This should also perform logging when needed. We'll call this abstraction ExceptionHandler. It's a façade based on the "Gang of Four" (GOF) Facade pattern (which the Design Patterns book says is used to "provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.") for the whole exception handling subsystem that handles all of the exceptions derived from BaseAppException. Here is the sample exception handling in a Struts Action method.

 
 
try{ 
    ... 
    DivisionDTO storeDTO = divisionBusinessDelegate 
      .getDivisionByNum(fromDivisionNum); 
}catch(BaseAppException ex){ 
    IExceptionHandler eh = ExceptionHandlerFactory 
      .getInstance().create(); 
    String expContext = "divisionAction.searchDivision"; 
    ExceptionDTO exDto = eh.handleException( 
        expContext , userId, ex); 
    ActionErrors errors = new ActionErrors(); 
        errors.add(ActionErrors.GLOBAL_ERROR 
          ,new ActionError( 
          exDto.getMessageCode())); 
    saveErrors(request, errors); 
    return actionMapping.findForward( 
        "SearchAdjustmentPage"); 
}

If you take a closer look at the exception handling code we just wrote, you might realize that you are writing similar code for each and every Struts method, which is a pain again. The objective is to remove boilerplate code as much as possible. We need to abstract it out again.

The solution is to use the Template Method design pattern (from GOF: "It is used to implement invariant parts of an algorithm once, and to leave it to subclasses to implement parts of the algorithm that can vary."). We need a base class that will contain the algorithm in the form of Template Method. The algorithm will contain the try-catch block for BaseAppException and a call to a dispatchMethod the method implementation (delegated to derived class) as shown below in a Struts based Action:

public abstract class BaseAppDispatchAction 
  extends DispatchAction{
...
protected static ThreadLocal 
  expDisplayDetails = new ThreadLocal();

public ActionForward execute(
  ActionMapping mapping,
  ActionForm form,
  HttpServletRequest request,
  HttpServletResponse response) throws Exception{
    ...
    try{
        String actionMethod = request
           .getParameter(mapping.getParameter());
        finalDestination =dispatchMethod(mapping,
          form, request, response,actionMethod);
    }catch (BaseAppException Ex) {
        ExceptionDisplayDTO expDTO = 
           (ExceptionDisplayDTO)expDisplayDetails
               .get();
        IExceptionHandler expHandler = 
            ExceptionHandlerFactory
                .getInstance().create();
        ExceptionDTO exDto = expHandler
            .handleException(
                expDTO.getContext(), userId, Ex);
        ActionErrors errors = new ActionErrors();
        errors.add(ActionErrors.GLOBAL_ERROR, 
            new ActionError(exDto
                .getMessageCode()));
        saveErrors(request, errors);
        return mapping.findForward(expDTO
            .getActionForwardName());
    } catch(Throwable ex){
           //log the throwable
           //throw ex;
    } finally {
           expDisplayDetails.set(null);
    }

In Struts, the DispatchAction::dispatchMethod method is used to forward the request to the appropriate Action method, named actionMethod.

Pages: 1, 2, 3, 4, 5, 6

Next Pagearrow