EJB最佳实践: 构建更好的异常处理框架

日期: 2009-11-23 作者:IBM developerworks网站 来源:TechTarget中国 英文

  嵌套的异常

  在设计可靠的异常处理方案时,要考虑的第一件事情就是对所谓的、低级或、系统级异常进行抽象化。这些核心Java异常通常会报告网络流量中的错误、JNDI或RMI问题,或者是应用程序中的其它技术问题。RemoteException 、EJBException和NamingException是企业Java编程中低级异常的常见例子。

  这些异常完全没有任何意义,由Web层的客户机接收时尤其容易混淆。如果客户机调用purchase()并接收到 NamingException,那么它在解决这个异常时会一筹莫展。同时,应用程序代码可能需要访问这些异常中的信息,因此不能轻易地抛弃或忽略它们。

  答案是提供一类更有用的异常,它还包含低级异常。清单1演示了一个专为这一点设计的简单ApplicationException:

  清单1.嵌套的异常
 

以下是引用片段:
 1 package com.ibm;
  2 import java.io.PrintStream;
  3 import java.io.PrintWriter;
  4 public class ApplicationException extends Exception {
  5        /** A wrapped Throwable */
  6        protected Throwable cause;
  7        public ApplicationException() {
  8            super(“Error occurred in application.”);
  9        }
10        public ApplicationException(String message)  {
11            super(message);
12        }
13        public ApplicationException(String message, Throwable cause)  {
14            super(message);
15            this.cause = cause;
16        }
17        // Created to match the JDK 1.4 Throwable method.
18        public Throwable initCause(Throwable cause)  {
19            this.cause = cause;
20            return cause;
21        }
22        public String getMessage() {
23            // Get this exception’s message.
24            String msg = super.getMessage();
25            Throwable parent = this;
26            Throwable child;
27            // Look for nested exceptions.
28            while((child = getNestedException(parent)) != null) {
29                // Get the child’s message.
30                String msg2 = child.getMessage();
31                // If we found a message for the child exception, 
32                // we append it.
33                if (msg2 != null) {
34                    if (msg != null) {
35                        msg += “: ” + msg2;
36                    } else {
37                        msg = msg2;
38                    }
39                }
40                // Any nested ApplicationException will append its own
41                // children, so we need to break out of here.
42                if (child instanceof ApplicationException) {
43                    break;
44                }
45                parent = child;
46            }
47            // Return the completed message.
48            return msg;
49        }
50        public void printStackTrace() {
51            // Print the stack trace for this exception.
52            super.printStackTrace();
53            Throwable parent = this;
54            Throwable child;
55            // Print the stack trace for each nested exception.
56            while((child = getNestedException(parent)) != null) {
57                if (child != null) {
58                    System.err.print(“Caused by: “);
59                    child.printStackTrace();
60                    if (child instanceof ApplicationException) {
61                        break;
62                    }
63                    parent = child;
64                }
65            }
66        }
67        public void printStackTrace(PrintStream s) {
68            // Print the stack trace for this exception.
69            super.printStackTrace(s);
70            Throwable parent = this;
71            Throwable child;
72            // Print the stack trace for each nested exception.
73            while((child = getNestedException(parent)) != null) {
74                if (child != null) {
75                    s.print(“Caused by: “);
76                    child.printStackTrace(s);
77                    if (child instanceof ApplicationException) {
78                        break;
79                    }
80                    parent = child;
81                }
82            }
83        }
84        public void printStackTrace(PrintWriter w) {
85            // Print the stack trace for this exception.
86            super.printStackTrace(w);
87            Throwable parent = this;
88            Throwable child;
89            // Print the stack trace for each nested exception.
90            while((child = getNestedException(parent)) != null) {
91                if (child != null) {
92                    w.print(“Caused by: “);
93                    child.printStackTrace(w);
94                    if (child instanceof ApplicationException) {
95                        break;
96                    }
97                    parent = child;
98                }
99            }
100        }
101        public Throwable getCause()  {
102            return cause;
103        }
104 } 

  清单 1 中的代码很简单;我们已经简单地将多个异常“串”在一起,以创建单个、嵌套的异常。但是,真正的好处在于将这种技术作为出发点,以创建特定于应用程序的异常层次结构。异常层次结构将允许EJB客户机既接收特定于业务的异常也接收特定于系统的信息,而不需要编写大量额外代码。

  异常层次结构

  异常层次结构应该从一些十分健壮而又通用的异常入手,如ApplicationException。如果您将顶级异常搞得太具体,那么其结果是您今后将不得不重新构造层次结构,以适应某些较通用的情况。

  因此,让我们假定您的应用程序要求NoSuchBookException、InsufficientFundsException和SystemUnavailableException。您不必创建这三个异常,让它们继承ApplicationException,然后只需提供极少几个必须的构造器来创建格式化的消息。清单 2 是此类异常层次结构的示例:

  清单 2. 异常层次结构

以下是引用片段:
1 package com.ibm.library;
2 import com.ibm.ApplicationException;
3 public class NoSuchBookException extends ApplicationException {
4        public NoSuchBookException(String bookName, String libraryName) {
5         super(“The book ‘” + bookName + “‘ was not found in the ‘” +
6             libraryName + “‘ library.”);
7     }
8 }

  当需要编写大量专用异常时,异常层次结构极大地简化了工作。对于一个异常,为每个异常类添加一个或两个构造器,所花费时间很少不超过几分钟。您还经常需要给这些更具体的异常(这些异常也是主应用程序异常的子类)提供子类,以提供更具体的异常。例如,您可能需要InvalidTitleException和BackorderedException来继承NoSuchBookException 。

  企业应用程序在构建时通常都不会注意异常处理。尽管依靠低级异常(如RemoteException和NamingException)很容易(有时也很诱人),但如果一开始就建立一个可靠的、深思熟虑的异常模型,则您将在应用程序上少花很多精力。创建一个嵌套的、层次结构化的异常框架将改进代码的可读性及其可用性。

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

相关推荐

  • 何时是创建门户应用最佳时机

    在创建出新企业门户应用,链接到现有系统之前,你可能需要检查一下这些系统,确保这些系统本身不需要重造。这样你可能就会重新考虑是否要创建新企业门户应用了。

  • 采用EJB开发的三个优势

    EJB是sun的服务器端组件模型,最大的用处是部署分布式应用程序。当然,还有许多方式可以实现分布式应用,类似微软的.net技术。

  • 构建高性能J2EE应用的十个技巧

    构建高性能的J2EE应用不但需要了解常用的实施技巧。下面介绍最常用的10种有效方法,可帮助架构设计师们快速成为这方面的专家。

  • WPS/WESB绑定:玩转EJB绑定(上)

    面向服务的体系架构(SOA)提出了把功能包装成服务的设计理念。服务组件架构(SCA)是一种实现SOA理念的方式。作为编程模型和框架,SCA定义了描述服务……