`
ariyue
  • 浏览: 338410 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

构建更好的异常处理框架

    博客分类:
  • java
阅读更多
企业应用程序在构建时常常对异常处理关注甚少,这会造成对低级异常(如 java.rmi.RemoteException 和 javax.naming.NamingException)的过度依赖。在 EJB 最佳实践的这篇专栏文章中,Brett McLaughlin 解释了为什么对异常处理投入一点关注就会给我们带来很大的帮助,并向您展示了两种简单技术,它们将帮助您正确地构建更健壮且有用的异常处理框架。
在本系列先前的技巧文章中,异常处理不属于讨论的核心范围之内。但是,您可能会发现一点,那就是我们一直都回避来自 Web 层的低级异常。我们向客户机提供诸如 ApplicationException 和 InvalidDataException 之类的异常,而没有让 Web 层处理象 java.rmi.RemoteException 或 javax.naming.NamingException 这样的异常。

远程和命名异常是系统级异常,而应用程序和非法数据异常是业务级异常,因为它们提交更适用的业务信息。当决定抛出何种类型的异常时,您应该总是首先考虑将要处理所报告异常的层。Web 层通常是由执行业务任务的最终用户驱动的,所以最好用它处理业务级异常。但是,在 EJB 层,您正在执行系统级任务,如使用 JNDI 或数据库。尽管这些任务最终将被合并到业务逻辑中,但是最好用诸如 RemoteException 之类的系统级异常来表示它们。

理论上,您可以让所有 Web 层方法预期处理和响应单个应用程序异常,正如我们在先前的一些示例中所做的一样。但这种方法不适用于长时间运行。让您的委派方法抛出更具体的异常,这是一个好得多的异常处理方案,从根本上讲,这对接收客户机更有用。在这篇技巧文章中,我们将讨论两种技术,它们将有助于您创建信息更丰富、更具体的异常,而不会生成大量不必要的代码。

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

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

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

清单 1. 嵌套的异常 package com.ibm;
import java.io.PrintStream;
import java.io.PrintWriter;
public class ApplicationException extends Exception {
/** A wrapped Throwable */
protected Throwable cause;
public ApplicationException() {
super("Error occurred in application.");
}
public ApplicationException(String message) {
super(message);
}
public ApplicationException(String message, Throwable cause) {
super(message);
this.cause = cause;
}
// Created to match the JDK 1.4 Throwable method.
public Throwable initCause(Throwable cause) {
this.cause = cause;
return cause;
}
public String getMessage() {
// Get this exception's message.
String msg = super.getMessage();
Throwable parent = this;
Throwable child;
// Look for nested exceptions.
while((child = getNestedException(parent)) != null) {
// Get the child's message.
String msg2 = child.getMessage();
// If we found a message for the child exception,
// we append it.
if (msg2 != null) {
if (msg != null) {
msg += ": " + msg2;
} else {
msg = msg2;
}
}
// Any nested ApplicationException will append its own
// children, so we need to break out of here.
if (child instanceof ApplicationException) {
break;
}
parent = child;
}
// Return the completed message.
return msg;
}
public void printStackTrace() {
// Print the stack trace for this exception.
super.printStackTrace();
Throwable parent = this;
Throwable child;
// Print the stack trace for each nested exception.
while((child = getNestedException(parent)) != null) {
if (child != null) {
System.err.print("Caused by: ");
child.printStackTrace();
if (child instanceof ApplicationException) {
break;
}
parent = child;
}
}
}
public void printStackTrace(PrintStream s) {
// Print the stack trace for this exception.
super.printStackTrace(s);
Throwable parent = this;
Throwable child;
// Print the stack trace for each nested exception.
while((child = getNestedException(parent)) != null) {
if (child != null) {
s.print("Caused by: ");
child.printStackTrace(s);
if (child instanceof ApplicationException) {
break;
}
parent = child;
}
}
}
public void printStackTrace(PrintWriter w) {
// Print the stack trace for this exception.
super.printStackTrace(w);
Throwable parent = this;
Throwable child;
// Print the stack trace for each nested exception.
while((child = getNestedException(parent)) != null) {
if (child != null) {
w.print("Caused by: ");
child.printStackTrace(w);
if (child instanceof ApplicationException) {
break;
}
parent = child;
}
}
}
public Throwable getCause() {
return cause;
}
}




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

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

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

清单 2. 异常层次结构 package com.ibm.library;
import com.ibm.ApplicationException;
public class NoSuchBookException extends ApplicationException {
public NoSuchBookException(String bookName, String libraryName) {
super("The book '" + bookName + "' was not found in the '" +
libraryName + "' library.");
}
}




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

企业应用程序在构建时通常都不会注意异常处理。尽管依靠低级异常(如 RemoteException 和 NamingException)很容易(有时也很诱人),但如果一开始就建立一个可靠的、深思熟虑的异常模型,则您将在应用程序上少花很多精力。创建一个嵌套的、层次结构化的异常框架将改进代码的可读性及其可用性。
详细内容:http://www-900.ibm.com/developerWorks/cn/java/j-ejb01283/index.shtml?n-j-04211
分享到:
评论

相关推荐

    基于TensorFlow深度学习框架的窃电分析研究.pdf

    在实际研究中,研究者发现,基于深度学习的TensorFlow框架模型能够有效完成异常用电模式的检测工作,且相比非深度学习检测模型来说,该模型具有更好的鲁棒性和准确性。此外,相比多层长短期记忆特征提取,所提取的...

    基于深度学习的用户异常用电模式检测

    针对电力用户的异常用电行为,提出一种基于深度学习的用户异常用电模式检测模型。利用Tensor Flow框架,构建了特征提取网络和多层特征匹配网络。...此外,与多层LSTM分类模型相比,所提模型具有更好的准确性和鲁棒性。

    基于深度学习的用户异常用电模式检测.pdf

    "基于深度学习的用户异常用电模式检测" 该论文提出了一种基于深度学习的用户异常用电模式检测模型,旨在解决电力自动化设备中非技术性损失的问题。...该模型可以更好地检测出异常用电数据,具有更好的准确性和鲁棒性。

    Spring Boot与Netty:构建高性能的网络应用

    本文将详细探讨如何在Spring Boot应用中集成Netty,以构建高性能的网络应用。...4. 稳定性:Netty 在设计和实现时考虑到了各种可能的问题和异常,它提供了强大的异常处理和恢复机制,确保应用的稳定运行。

    JAVA毕业设计之springboot网吧管理系统项目(springboot完整源码+说明).zip

    同时,也提供了日志管理、异常处理等功能,能够更好地帮助管理员了解系统运行情况和进行故障排查。总之,这个项目是一个功能完善、技术先进的网吧管理系统,能够帮助网吧管理员更好地运营和管理网吧,提高管理效率和...

    JSTL详细标签库介绍

    target=_blank>构建更好的异常处理框架</A> <LI><A title="关于runtime exception和checked exception" href="http://www.jspcn.net/htmlnews/11453821828901962.html" target=_blank>关于runtime exception...

    Ciro:Ciro是一个MVC PHP框架,用于启动个人项目。 设计简单轻巧。 演示PHP框架的核心构建块

    Ciro PHP框架Ciro是一个MVC PHP框架,可以快速启动项目,它的设计简单,可配置,模块化,解耦,可扩展且轻巧,使构建更好和易于维护PHP代码变得更加容易。 Ciro开箱即用: 命名间隔的PSR-4结构单一入口点PHP应用程序...

    E_B_P:异常最佳实践(收集框架)

    这个微小的框架提供了不同的方法来管理异常以更好的方式所以,我们有: Stackless Exception 和 RuntimeStacklessException (Java 5,6,7,8) 交换策略以交换 StackTraces StackSwapper.swap([exc1],[exc2]); ...

    基于模型编排的实时数据挖掘框架源码+项目说明.zip

    我们现在将星盘内核框架开源,旨在和社区一起共创更好的实时数据挖掘产品。 # 核心功能 + **交互式的流程编排** + 星盘基于BPM模型,设计了一种"代码化的流程图"流程图语言FlowDSL, 用于编制和编排微服务调用,...

    轻量级JAVA实时业务风控系统框架.zip

    要将任意维度的历史数据(可能半年或更久)实时统计出结果,需要将数据提前安装特殊结果准备好(由于事件的维度数量不固定的,选取统计的维度也是随意的,所以不是在关系数据库中建几个索引就能搞定的),需要利用...

    java面试手册及各类java书籍

    高级特性篇:涵盖Java中的高级特性,如集合框架、泛型、异常处理、多线程、网络编程等,帮助读者提升Java编程能力。 框架篇:介绍Java中常用的框架,如Spring、Hibernate、MyBatis等,使读者能够快速掌握框架的使用...

    46道java基础知识面试题详解含答案(值得珍藏)

    例如,对于面向对象编程的概念、异常处理机制、集合框架的使用等方面的知识,如果求职者能够清晰地解释并给出相应的示例代码,就能够让面试官了解到其扎实的技术基础和良好的编程习惯。 其次,熟练掌握Java基础知识...

    基于IBMRationalRobot的自动化功能测试框架

    本文介绍了构建在IBMRationalRobot基础之上的自动化功能测试框架,来帮助组织更好的进行自动化的功能测试。2.现实的挑战2.1自动化测试的迫切需求随着业务的变化,软件产品的种类越来越多,软件产品的升级越来越快,...

    基于SSM+Vue的智慧城市实验室主页系统.zip

    数据分析模块则可以对实验室的数据进行统计和分析,帮助决策者做出更好的决策。此外,系统还包括了公告发布、预约管理、文件共享等多个实用的功能模块。 总的来说,基于SSMVue的智慧城市实验室主页系统是一个集现代...

    使用 PyTorch 实现的深度学习 ECG 模型

    通过结合不同类型的神经网络层,研究人员可以构建复杂的深度学习模型,从而更好地理解和分析心电图数据。 PyTorch 提供了丰富的工具和库,简化了深度学习模型的开发和训练过程。研究人员可以利用 PyTorch 中的自动...

    express-typescript-starter:You您不会在Node Js中讨厌的构建API

    定制验证器可以更好,更严格地验证您的请求( )。基本的安全功能归功于。借助event 轻松进行。从进行简单迁移快速建立数据库。通过我们自己的工厂轻松进行数据播种。验证系统感谢 。 Docker感谢 。多亏了基于类才能...

    2023年丰富的Java源码学习资料.pdf

    这使得Java具有更好的代码组织性、可维护性和可扩展性。 3. 强大的生态系统:Java拥有丰富的类库和框架,其中最著名的是Java Development Kit (JDK)提供的标准类库。这些类库和框架可以帮助开发人员快速构建各种...

    Java高并发高性能分布式框架从无到有微服务架构设计.doc

    它具有内存和磁盘存储,缓存加载器,缓存扩展,缓存异常处理程序,一 个gzip缓存servlet过滤器,支持REST和SOAP api等特点。MapDB: mapdb是一个内嵌的纯java的数据库,提供了并发的HashMap、TreeMap、Queue,可以基 于...

Global site tag (gtag.js) - Google Analytics