An exception handling framework for J2EE applications

Source: Internet
Author: User
Tags define abstract

Scenarios with checked and unchecked exceptions

Have you ever wondered why you should place a try-catch Block around the compiled code block, that is, you know that you cannot handle these exceptions, but is it only suitable to put them in catch blocks? You may want to know why you cannot put this job in a centralized place? In most cases, this isFront-end Controller. In other words, developers will not be disturbed by them, because they do not have to be asked a lot. However, what happens if a method name contains a throws clause? Developers must either capture these exceptions or put them in the throws clause of their methods. This is the root cause of pain! Fortunately, Java APIs have a class of exceptions called unchecked exception that do not need to be captured. However, there is still a problem: what determines the checked exceptions and the unchecked exceptions? The following provides some guiding principles:

  • An unchecked exception occurs when the end user cannot take valid operations. For example, the fatal and unrecoverable exceptions should be unchecked. Taking XMLParseException (thrown when parsing XML files) as a checked exception does not make sense, because the only way to take it is to solve the fundamental problem based on exception tracking. You can create a custom unchecked exception by extending java. lang. RuntimeException.
  • In applications, user-related exceptions should be checked exceptions. Checked Exceptions require clients to capture them. You may ask why all exceptions are considered as unchecked. The problem is that some exceptions cannot be captured at the right position. This will cause more problems, because errors can only be identified at runtime. Examples of checked exceptions include service validation exceptions and security exceptions.
The exception throw policy only captures basic application exceptions (assumed to be BaseAppException) and declares in the throws clause

In most J2EE applications, the decision on which error message should be displayed for an exception can only be made in the presentation layer. This raises another question: Why can't we put this decision in a public place? In a J2EE application,Front-end ControllerIs a centralized location for common processing.

In addition, there must be a general mechanism for transmitting exceptions. Exceptions also need to be handled in a universal way. Therefore, we always need to capture the BaseAppException of the basic application on the Controller side. This means that we need to put the BaseAppException exception (only this exception) into the throws clause of each method that can throw the checked exception. The concept here is to use polymorphism to hide the actual implementation of exceptions. We capture BaseAppException In the controller, but the thrown exception instance may be any of several derived exception classes. With this method, we can gain a lot of flexibility in exception handling:

  • You do not need to add a large number of checked exceptions in the throws clause. Only one exception is required in the throws clause.
  • You do not need to use a confusing catch Block for exceptions in the application. If you need to process them, a catch block (for BaseAppException) is enough.
  • Developers do not need to handle exceptions in person (logging and getting error codes ). This abstraction is completed by ExceptionHandler, which will be discussed later in this article.
  • Even if more exceptions are introduced to the method implementation later, the method name will not change, so you do not need to modify the client code, otherwise it will cause a chain reaction. However, the thrown exception must be specified in the Javadoc of the method so that the client can see the method constraints.

The following is an example of throwing a checked exception:

public void updateUser(UserDTO userDTO)    throws BaseAppException{     UserDAO userDAO = new UserDAO();     UserDAO.updateUser(userDTO);     ...     if(...)         throw new RegionNotActiveException(             "Selected region is not active"); }  Controller Method: ... try{     User user = new User();     user.updateUser(userDTO); }catch(BaseAppException ex){     //ExceptionHandler is used to handle     //all exceptions derived from BaseAppException } ... 

So far, we have explained that for all methods that may throw a checked exception and be called by the Controller, the throws clause should only contain the checked exception. However, this actually implies that we cannot include any other application exceptions in the throws clause. However, what should I do if I need to execute the business logic based on some types of exceptions in the catch Block? To handle such cases, the method can also throw a specific exception. Remember, this is a special case that developers cannot take for granted. Similarly, the application exceptions discussed here should extend the BaseAppException class. The following is an example:

CustomerDAO method: //throws CustomerNotActiveException along with //BaseAppException public CustomerDTO getCustomer(InputDTO inputDTO)     throws BaseAppException,         CustomerNotActiveException {     . . .     //Make a DB call to fetch the customer      //details based o­n inputDTO     . . .     // if not details found     throw new CustomerNotActiveException(         "Customer is not active"); }  Client method:  //catch CustomerNotActiveException //and continues its processing public CustomerDTO getCustomerDetails(   UserDTO userDTO)     throws BaseAppException{     ...     CustomerDTO custDTO = null;     try{         //Get customer details          //from local database         customerDAO.getCustomerFromLocalDB();     }catch(CustomerNotActiveException){         ...         return customerDAO             .activateCustomerDetails();     } } 
Handle unchecked exceptions at the web application level

All unchecked exceptions should be handled at the web application layer. You can configure a web page in the web. xml file to display the page to end users when an unchecked exception occurs in the application.

Encapsulate third-party exceptions into application-specific exceptions

When an exception originated from another external interface (component), it should be encapsulated into an application-specific exception and processed accordingly.

Example:

try {     BeanUtils.copyProperties(areaDTO, areaForm); } catch (Exception se) {     throw new CopyPropertiesException(         "Exception occurred while using              copy properties", se); } 

Here, CopyPropertiesException extends java. lang. RuntimeException and we will record it. The Exception is caught, rather than the specific checked Exception that can be thrown by the copyProperties method, because for all these exceptions, we will throw the same unchecked CopyPropertiesException Exception.

Too many exceptions

You may want to know whether the exception class will overflow if we create an exception for each error message? For example, if "Order not found" is an error message of OrderNotFoundException, you certainly won't set the error message of CustomerNotFoundException to "Customer not found" for obvious reasons: these two exceptions represent the same meaning. The only difference is that they have different contexts. Therefore, if you can specify the context when handling exceptions, we can merge these exceptions into a RecordNotFoundException. The following is an example:

try{     ... }catch(BaseAppException ex){     IExceptionHandler eh =ExceptionHandlerFactory       .getInstance().create();     ExceptionDTO exDto = eh.handleException(         "employee.addEmployee", userId, ex); } 

Here, the employee. addEmployee context will be appended to an error code with context-sensitive exceptions, resulting in a unique error code. For example, if the error code of RecordNotFoundException is errorcode. recordnotfound, the final error code of this context will become errorcode. recordnotfound. employee. addEmployee, which is the only error code for this context.

However, we need to give a warning: If you want to use multiple interfaces in the same client method, and these interfaces can throw a RecordNotFoundException exception, it is very difficult to know which entity causes this exception. If the business interface is public and can be used by various external clients, we recommend that you use only specific exceptions instead of general exceptions such as RecordNotFoundException. Context-specific exceptions are very useful for database-based recoverable exceptions, because in this case, exception classes are always the same, and only the context in which they appear is different.

Exception hierarchies of J2EE applications

As discussed earlier, we need to define an exception base class called BaseAppException, which contains the default behavior of all application exceptions. We will place this base class in the throws clause of all methods that may throw a checked exception. All the checked exceptions of the application should be subclasses of this base class. There are multiple methods to define abstract error handling. However, the difference is more related to the business class rather than the technology. Abstract error handling can be divided into the following types. All these exception classes are derived from BaseAppException.

Checked exception
  • Service exception: An exception occurred when executing the business logic. BaseBusinessException is the base class for such exceptions.
  • Database exception: The exception thrown when interacting with the persistence mechanism. BaseDBException is the base class of this type of exception.
  • Security Exception: Security Operation exception. The base class of this type of exception is BaseSecurityException.
  • Confirm exceptions: Used when an end user receives confirmation to execute a specific task. The base class of this type of exception is BaseConfirmationException.
Unchecked exception
  • System exception: Sometimes we want to use the unchecked exception. For example, if you do not want to handle exceptions from third-party library APIs, you want

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.