本文转载,最有意思的是 if(e.getCause() instanceof MailSendException) 而e代表MailException。
1. 异常的种类
Java异常机制是为了对程序中可能出现的已知错误进行捕获,并进行相应处理。从是否反馈给用户来看,存在三类异常:
数据库操作异常:
系统异常:这类异常(如 应用服务器异常)由系统本身的低级异常引起,例如数据库连接失败、内存溢出、空指针异常等等,这类异常不需要出现在前台,因为用户看不懂也没有必要看到这些异常信息。这类异常需要在日志中进行完整记录以供日后开发人员进行查看分析。
应用异常:即自定义异常(业务异常,如 权限不够等),这类异常需要通过前台反馈给用户,友好提示用户当前操作异常。应用异常通过系统异常转换而来,例如新建用户时,发生“主键冲突异常”,则需要在UserinfoDao中将“主键冲突异常”捕获,并转换为应用异常,异常提示信息设为“该用户名XXX已存在,请使用其它用户名”,并将该异常信息反馈给前台。只要系统异常影响到的用户的当前操作,就必须给用户提示信息,比如“系统后台发生错误,请稍后再试”等。应用异常应按照提示方式的异常进行分类,对应不同的提示页面。
2. 日志的作用
系统运行日志:记录系统的运行情况,跟踪代码运行时轨迹;
异常和错误日志:记录异常堆栈信息,以供开发人员查看分析;
业务日志:记录业务信息和用户操作,例如用户登录、删除数据、更新数据等。
3. 异常的处理原则
1、避免过大的try块,不要把不会出现异常的代码放到try块里面,尽量保持一个try块对应一个或多个异常。
2、细化异常的类型,不要不管什么类型的异常都写成Excetpion。catch语句表示我们预期会出现某种异常,而且希望能够处理该异常。异常类的作用就是告诉Java编译器我们想要处理的是哪一种异常,然后针对具体的异常类进行不同的处理。例如在DAO层中我们应该只捕获SQLException或DataAccessException(Spring自定义的数据访问异常类)这些数据库异常类,其他的异常NullPointException、NumberFormatException等应通过检测代码增加其健壮性来解决,而不应该通过try..catch(Exception e)…语句捕获所有的异常。
3、不要把自己能处理的异常抛给别人,不要忽略捕获的异常,捕获到后要么处理,要么转译,要么重新抛出新类型的异常。。处理方式包括:
Ø 处理异常。针对该异常采取一些行动,例如修正问题、提醒某个人或进行其他一些处理,要根据具体的情形确定应该采取的动作。再次说明,调用printStackTrace算不上已经“处理好了异常”。
Ø 重新抛出异常。处理异常的代码在分析异常之后,认为自己不能处理它,重新抛出异常也不失为一种选择。
Ø 把该异常转换成另一种异常。大多数情况下,这是指把一个低级的异常转换成应用级的异常(其含义更容易被用户了解的异常)。
4、如果对catch块尽量保持一个块捕获一类异常,在catch语句中尽可能指定具体的异常类型,必要时使用多个catch。
例:
try {
} catch (Exception e) {
e.printStackTrace();
log.error("UserinfoDao execute() failed");
}
这段代码捕获了异常,但实际上对异常并没有进行处理,可以算得上Java编程中的杀手。按照这个方式,在DAO层发生异常被忽略,Service层就认为DAO层运行正确,就不会回滚,事务控制就没有任何作用!!!
Ø printStackTrace对调试程序有帮助,但程序调试阶段结束之后,printStackTrace就不应再在异常处理模块中担负主要责任。
Ø 日志尽量在系统中的各个出口,例如Action、调度方法等处统一记录,可减少工作量,况且日志"UserinfoDao execute() failed”并没有说明异常的详细信息,没有必要向日志输出这句话。
Ø 即使catch中加入throw new RuntimeException(e);语句。如果捕获的异常是RuntimeException,更没有必要将异常再次转化为RuntimeException,这样不仅异常的本身的类型丢失,重新定义异常也造成一定消耗。
所以该处的处理原则应是:如果该处异常需要能转化为业务异常反馈给用户,则需要捕捉低级异常并转换成业务异常上抛,否则不做任何处理!!!
6、不要用try...catch参与控制程序流程,异常控制的根本目的是处理程序的非正常情况。
4. 开发中异常的处理方式
本系统使用SSH框架,DAO+Service+Action三层架构,捕获原则是只有将低级系统异常转化为应用异常的需要才进行捕捉。
各层的处理方式如下:
DAO层:引发DAO异常的问题往往是不可恢复的,如数据连接失败,SQL语句存在语法错误,强制捕捉的检查型异常除了限制开发人员的自由度以外,并没有提供什么有意义的作用。因此,Spring的异常体系都是建立在运行期异常的基础上,这些异常都继承于DataAccessException(RuntimeException异常子类),所以,除了出于将低级系统异常转化为应用异常的需要,没有必要捕获异常,让DAO类自动上抛异常即可。
Service层:只捕获自定义应用异常,其他异常上抛。
Action:只捕获自定义应用异常,其他异常上抛。Struts2提供了异常拦截器,拦截器会将定义的异常捕获,记录日志,然后根据配置的异常的类型顺序跳转到相应的页面。配置如下:
struts.xml配置文件
<interceptor-ref name="defaultStack">
<param name="exception.logEnabled">true</param><!--开启日志记录 -->
<param name="exception.logLevel">error</param><!-- 日志级别为ERROR -->
</interceptor-ref>
<global-exception-mappings><!—异常类和跳转页面配置 -->
<exception-mapping result="basicerror" exception="com.***.***.exception.BasicException"/>
<exception-mapping result="error" exception="java.lang.Exception"/>
</global-exception-mappings>
com.***.***.exception.BasicException为自定义应用异常,如果客户端的请求执行过过程中产生com.***.***.exception.BasicException异常,则会自动转到basicerror页面,从而给用户相应的提示。
basicerror页面
<%@ page language="java" contentType="text/xml; charset=UTF-8" pageEncoding="UTF-8"%>${exception.message }
5. 自定义应用异常
异常名称 |
说明 |
com.***.***.exception.BasicException |
基础异常类,本系统中所有的自定义异常类均需继承本类 |
com.***.***.exception. DuplicateKeyException |
主键冲突异常,继承BasicException |
例:
Userinfo save方法异常处理
@Override
public void save(Userinfo entity) {
try {
super.save(entity);
} catch (DataIntegrityViolationException e) {
if(e.getCause().getCause() instanceof SQLException){
SQLException sqlE = (SQLException)e.getCause().getCause();
if(sqlE.getErrorCode()==1){//ORACLE主键冲突异常代码
throw new DuplicateKeyException("用户名:"+entity.getUserid()+"已存在,请使用其他用户名");
}
}
}
}
6. 日志配置
系统中目前配置了三个日志记录器,一个为异常记录器,专门记录异常信息,日志文件到达一定大小后将产生新的日志文件,文件名称为exception.log,另一个为系统运行记录器,按照日期记录所有的日志信息。
相关推荐
### 深入理解Java异常处理机制 #### 引言 异常处理机制是任何现代编程语言不可或缺的一部分,尤其是在像Java这样的面向对象的语言中更是如此。Java的异常处理机制旨在帮助开发者编写更健壮、更易于维护的代码。...
总的来说,这个实验旨在让你掌握Java异常处理的基本原理和实践,以及log4j的日志记录功能。通过实际操作,你将能够更有效地调试代码,定位问题,为后续的Java学习打下坚实的基础。在实际项目中,良好的异常处理和...
总结来说,Java异常处理机制提供了一种结构化的方法来处理程序运行时的错误,通过try-catch-finally结构捕获和处理异常,同时,利用断言进行内部逻辑验证,以及日志记录来跟踪程序行为。这样的机制增强了代码的健壮...
### JAVA的异常处理机制 #### 引言 Java作为一种广泛使用的编程语言,其强大的功能不仅体现在高效的代码编写上,还在于其对程序错误处理的高度灵活性与健壮性。Java的异常处理机制是Java语言的一项重要特性,它...
Exception类是所有Java异常的基类,它继承自Throwable类。常见的异常类有IOException、NullPointerException、ArrayIndexOutOfBoundsException等。 三、异常处理机制 Java提供了五个关键字来处理异常:try、catch、...
### Java异常机制深入研究 #### 一、Java异常概述与分类 Java中的异常处理机制是其强大特性之一,它能够帮助开发者有效地管理程序运行时出现的错误情况,从而提高程序的健壮性和可维护性。Java中的异常主要分为三...
为了深入理解和正确实施这一机制,本文将阐述有效处理Java异常的三个重要原则,并结合JCheckbook类的示例进行讨论。 首先,Java中的异常是由Throwable类的层次结构所定义的,其中包含了Error、Exception以及...
本文将围绕Java异常处理机制展开,探讨其核心概念、分类、处理技巧,并简述自定义异常类的创建方法,以帮助读者在实际开发中更有效地进行异常处理。 一、什么是异常? 异常是Java程序在运行过程中发生的不正常事件...
以下是对Java异常处理的一些误区和经验总结。 **误区一:过度使用try-catch块** 有些开发者习惯于在每个函数的开始部分都套用try-catch块,以为这样可以捕捉所有可能出现的异常。实际上,这种做法使得代码变得混乱...
JAVA异常机制是JAVA编程中的重要组成部分,它主要用于处理程序运行时出现的错误情况。当JAVA代码中发生异常时,程序会立即停止当前流程,转而寻找合适的异常处理代码,这个过程就是异常的抛出和捕获。JAVA异常分为...
### JAVA DAO 事务界定、异常处理与日志记录 #### 一、引言 在现代软件开发中,尤其是在企业级应用领域,数据访问对象(Data Access Object,简称 DAO)模式是一种广泛采用的设计模式,用于将低级别的数据访问逻辑...
JAVA基础第6章异常处理机制练习题 本资源是关于JAVA基础第6章异常处理机制的练习题,涵盖了异常处理机制的基本概念、try-catch-finally语句、throw和throws关键字、自定义异常类等知识点。 1. 异常处理机制的基本...
综上所述,Java Web开发中的异常处理涉及多种策略,包括基础的try-catch-finally、Servlet的异常处理机制、Spring的全局异常处理器,以及Web.xml配置。而AOP技术则提供了更为灵活的异常处理手段,允许我们在不侵入...
本文将深入探讨Java中的异常类处理,包括异常的分类、处理机制以及如何有效地利用源码和工具进行调试。 首先,Java中的异常分为检查型异常(Checked Exceptions)和运行时异常(Runtime Exceptions)。检查型异常是...
以下将深入探讨全面掌握Java异常处理机制的关键点,并分析给定代码中存在的问题。 1. **异常处理的基本结构** - `try` 块:包含可能会抛出异常的代码。 - `catch` 块:捕获并处理`try`块中抛出的异常。 - `...
总之,Java异常处理机制是保证程序健壮性和容错能力的关键。理解并熟练运用异常处理,能够提高程序的稳定性,减少因异常导致的程序中断,从而提供更好的用户体验。开发者应养成良好的异常处理习惯,确保程序在遇到...
这篇博文“Java异常框架设计”可能探讨了如何有效地利用Java的异常处理机制来构建可靠的系统。在这个讨论中,我们将深入理解Java异常的基本概念、异常分类、以及如何通过良好的框架设计提升代码的可读性和可维护性。...
Java异常处理是编程中至关重要的一个环节,它用于在程序执行期间处理错误和不正常的情况。本文深入探讨了高效Java异常处理框架,旨在提高代码的健壮性和稳定性。首先,文章介绍了异常的基本概念和Java异常体系结构。...
Java异常处理是编程中至关重要的一个环节,它确保了程序在遇到错误或异常情况时能够以优雅的方式终止,而不是突然崩溃。在这个简单的Java异常处理主题中,我们将深入探讨异常的设定、捕捉和处理过程,以及如何在...
在Java中,异常处理机制是通过try-catch-finally语句块实现的。当一个异常在try块中被抛出时,控制权会立即转移到相应的catch块。catch块是用来处理特定类型的异常,而finally块则包含需要在任何情况下都要执行的...