[size=large]1异常的作用
业务处理流程和错误处理流程分离,使代码更简洁,易懂。
便于程序员调试和排错。
异常捕获,向用户提供友好信息。
......
2异常使用要点
重新抛出的异常必须保留原来的异常,即throw new NewException("message", e); 而不能写成throw new NewException("message")。
在所有异常被捕获且没有重新抛出的地方必须写日志。
如果属于正常异常的空异常处理块必须注释说明原因,否则不允许空的catch块。
针对第一点举个例子:[/size]
[size=large]3三层结构
在action、service和dao三层结构中处理异常,一般是dao层抛出HibernateException(不用捕获,为runtimeException),在service层抛出自定义的业务异常ServiceException,最后在action中统一捕获自定义的业务异常ServiceException通知用户(可以为所有的action定义一个拦截器ExceptionInterceptor捕获这个自定义的业务异常,这样就不必每个action里都写try catch)。
需要注意的是在service中抛出业务异常最好继承RuntimeException。因为事务一般放在service层,如果抛出的是checked异常,事务不会回滚(可以配置),这是spring的特性。spring抛出的是unchecked异常,Hibernate3也从检查性异常转为非检查性异常(HibernateException),因此service层调用dao层抛出HibernateException异常时,service层定义的事务将会回滚。
查资料时看见有前辈总结的spring的异常设计,摘抄如下:
一个统一的异常层次结构对于提供服务抽象是必需的。 最重要的就是org.springframework.dao.DataAccessException以及其子类了。 需要强调的是Spring的异常机制重点在于应用编程模型。与SqlException和其他数据存取API不同的是: Spring的异常机制是为了让开发者使用最少, 最清晰的代码。DataAccessException和其他底层异常都是非检查性异常(unchecked exception)。 spring的原则之一就是基层异常就应该是非检查性异常. 原因如下:
1. 基层异常通常来说是不可恢复的。
2. 检查性异常将会降低异常层次结构的价值.如果底层异常是检查性的, 那么就需要在所有地方添加catch语句进行捕获。
3.try/catch代码块冗长混乱, 而且不增加多少价值。
使用检查异常理论上很好, 但是实际上好象并不如此。
Hibernate3也将从检查性异常转为非检查性异常。
[/size]
业务处理流程和错误处理流程分离,使代码更简洁,易懂。
便于程序员调试和排错。
异常捕获,向用户提供友好信息。
......
2异常使用要点
重新抛出的异常必须保留原来的异常,即throw new NewException("message", e); 而不能写成throw new NewException("message")。
在所有异常被捕获且没有重新抛出的地方必须写日志。
如果属于正常异常的空异常处理块必须注释说明原因,否则不允许空的catch块。
针对第一点举个例子:[/size]
class NewException extends Exception {
}
public class ExceptionTest {
public void test() {
try {
throw new NewException();
} catch (NewException e) {
//throw new RuntimeException("检测异常转为非检测异常。", e);
throw new RuntimeException("检测异常转为非检测异常。");
}
}
public static void main(String[] args) {
ExceptionTest et = new ExceptionTest();
et.test();
}
}
/*
throw new RuntimeException("检测异常转为非检测异常。", e)结果:
Exception in thread "main" java.lang.RuntimeException: 检测异常转为非检测异常。
at cn.yang.ExceptionTest.test(ExceptionTest.java:12)
at cn.yang.ExceptionTest.main(ExceptionTest.java:18)
Caused by: cn.yang.NewException
at cn.yang.ExceptionTest.test(ExceptionTest.java:10)
... 1 more
*/
/*
throw new RuntimeException("检测异常转为非检测异常。")结果:
Exception in thread "main" java.lang.RuntimeException: 检测异常转为非检测异常。
at cn.yang.ExceptionTest.test(ExceptionTest.java:12)
at cn.yang.ExceptionTest.main(ExceptionTest.java:18)
*/
[size=large]3三层结构
在action、service和dao三层结构中处理异常,一般是dao层抛出HibernateException(不用捕获,为runtimeException),在service层抛出自定义的业务异常ServiceException,最后在action中统一捕获自定义的业务异常ServiceException通知用户(可以为所有的action定义一个拦截器ExceptionInterceptor捕获这个自定义的业务异常,这样就不必每个action里都写try catch)。
需要注意的是在service中抛出业务异常最好继承RuntimeException。因为事务一般放在service层,如果抛出的是checked异常,事务不会回滚(可以配置),这是spring的特性。spring抛出的是unchecked异常,Hibernate3也从检查性异常转为非检查性异常(HibernateException),因此service层调用dao层抛出HibernateException异常时,service层定义的事务将会回滚。
查资料时看见有前辈总结的spring的异常设计,摘抄如下:
一个统一的异常层次结构对于提供服务抽象是必需的。 最重要的就是org.springframework.dao.DataAccessException以及其子类了。 需要强调的是Spring的异常机制重点在于应用编程模型。与SqlException和其他数据存取API不同的是: Spring的异常机制是为了让开发者使用最少, 最清晰的代码。DataAccessException和其他底层异常都是非检查性异常(unchecked exception)。 spring的原则之一就是基层异常就应该是非检查性异常. 原因如下:
1. 基层异常通常来说是不可恢复的。
2. 检查性异常将会降低异常层次结构的价值.如果底层异常是检查性的, 那么就需要在所有地方添加catch语句进行捕获。
3.try/catch代码块冗长混乱, 而且不增加多少价值。
使用检查异常理论上很好, 但是实际上好象并不如此。
Hibernate3也将从检查性异常转为非检查性异常。
[/size]