异常的作用
Java异常机制是为了对程序中可能出现的已知错误进行捕获,并进行相应处理。从是否反馈给用户来看,存在两类异常:
系统异常:
这类异常由系统本身的低级异常引起,例如数据库连接失败、内存溢出、空指针异常等等,这类异常不需要出现在前台,因为用户看不懂也没有必要看到这些异常信息。这类异常需要在日志中进行完整记录以供日后开发人员进行查看分析。
应用异常:
即自定义异常,这类异常需要通过前台反馈给用户,友好提示用户当前操作异常。应用异常通过系统异常转换而来,例如新建用户时,发生“主键冲突异常”,则需要在UserinfoDao中将“主键冲突异常”捕获,并转换为应用异常,异常提示信息设为“该用户名XXX已存在,请使用其它用户名”,并将该异常信息反馈给前台。只要系统异常影响到的用户的当前操作,就必须给用户提示信息,比如“系统后台发生错误,请稍后再试”等。应用异常应按照提示方式的异常进行分类,对应不同的提示页面。
异常的处理原则
1、避免过大的try块,不要把不会出现异常的代码放到try块里面,尽量保持一个try块对应一个或多个异常。
2、细化异常的类型,不要不管什么类型的异常都写成Excetpion。catch语句表示我们预期会出现某种异常,而且希望能够处理该异常。异常类的作用就是告诉Java编译器我们想要处理的是哪一种异常,然后针对具体的异常类进行不同的处理。例如在DAO层中我们应该只捕获SQLException或DataAccessException(Spring自定义的数据访问异常类)这些数据库异常类,其他的异常NullPointException NumberFormatException等应通过检测代码增加其健壮性来解决,而不应该通过try..catch(Exception e)…语句捕获所有的异常。
3、不要把自己能处理的异常抛给别人,不要忽略捕获的异常,捕获到后要么处理,要么转译,要么重新抛出新类型的异常。处理方式包括:
处理异常。针对该异常采取一些行动,例如修正问题、提醒某个人或进行其他一些处理,要根据具体的情形确定应该采取的动作。再次说明,调用printStackTrace算不上已经“处理好了异常”。
重新抛出异常。处理异常的代码在分析异常之后,认为自己不能处理它,重新抛出异常也不失为一种选择。
把该异常转换成另一种异常。大多数情况下,这是指把一个低级的异常转换成应用级的异常(其含义更容易被用户了解的异常)
如果对catch块尽量保持一个块捕获一类异常,在catch语句中尽可能指定具体的异常类型,必要时使用多个catch。
开发中异常的处理方式
DAO+Service+Action三层架构,捕获原则是只有将低级系统异常转化为应用异常的需要才进行捕捉。
DAO层:
引发DAO异常的问题往往是不可恢复的,如数据连接失败,SQL语句存在语法错误,强制捕捉的检查型异常除了限制开发人员的自由度以外,并没有提供什么有意义的作用。因此,Spring的异常体系都是建立在运行期异常的基础上,这些异常都继承于DataAccessException(RuntimeException异常子类),所以,除了出于将低级系统异常转化为应用异常的需要,没有必要捕获异常,让DAO类自动上抛异常即可。
Service层:
只捕获自定义应用异常,其他异常上抛。
Action:
只捕获自定义应用异常,其他异常上抛。Struts2提供了异常拦截器,拦截器会将定义的异常捕获,记录日志,然后根据配置的异常的类型顺序跳转到相应的页面