锁定老帖子 主题:浅谈web开发中的异常
精华帖 (0) :: 良好帖 (0) :: 新手帖 (8) :: 隐藏帖 (2)
|
|
---|---|
作者 | 正文 |
发表时间:2009-01-15
最后修改:2009-02-16
序: 异常,估计n多人都知道,至于那些定义、分类,我就不扯了。 在web开发中,凡是过来的人都应该知道,在action层调用义务层处理后,成功执行还好, 非成功执行就得通过某种方式通知action,然后action才知道将要显示何种提示信息给用户。 说到这,那就进入今天的话题了。 正文----开整 在web开发中异常应该有两类,一类为java程序中定义的异常,即如果按照我们设想的不应该 出现的异常,而另一类就是开发中很重要的业务异常。 何为业务异常呢,先举个例子说明一下,例如在修改一个用户信息时,传递用户的年龄(age)不 应该大于其父母亲的年龄,因此在service层中必然会做一个和父母亲年龄作比较的业务判断, 一旦判断失败,在通常的处理中是返回一个标识,而我认为在业务中我们应该只关心正确流程, 也就是说整个程序没有执行失败的返回路径,作为替代,我们定义一种异常,向上层抛出,以标 识的失败,这种异常就是我们称为的业务异常。 在action层,业务异常是应该要捕获的,并提示相应的信息给用户,这样用户才知道哪里出了错。 而对于其他异常,一旦出现,普通的做法是,定义一个页面,提示:系统正忙,请稍后再试。。。 如果是使用struts2进行开发的时候,对于业务异常,可以根据相应的异常标识,使用addActionError 等,返回INPUT页面,提示用户相应的信息;对于其他异常,可以使用在struts的包中定义一个 GlobalException来捕获,然后在result中返回公共的异常处理页面,如上面提到的系统正忙页面。 下面是一个简单的ServiceException异常类。 public class ServieException { //异常码,标识异常,也可以是国际化资源文件中的key值 private long exceptionCode; //异常参数,也可以是国际化资源文件中对应key标识的资源所需的参数 private String[] parameters; //构造器 public ServiceException(long exceptionCode, String... parameters) { this.exceptionCode = exceptionCode; this.parameters = parameters; } public long getExceptionCode() { return exceptionCode; } public void setExceptionCode(long exceptionCode) { this.exceptionCode = exceptionCode; } public String[] getParameters() { return parameters; } public void setParameters(String[] parameters) { this.parameters = parameters; } } 如果exceptionCode对应的是国际化资源文件中的key值,那么在action调用service层方法 时,一旦出现异常(ServiceException e),便可以使用如下语句 addActionError(getExceptionCode, getParameters()); return INPUT; 这样就可以把相关业务异常所代表的信息提示给用户。 注意,并不是每个action都可以定义INPUT页面的,所以在实际应用中,还应该提供一个公共 的失败页面,以供那些不能返回INPUT的页面,提示错误信息。当然,最好也提供一个公共成 功的页面,好事成双嘛。哈哈。。。 简单理解,请批评指教。 OK,打完收工 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-01-15
业务的异常的定义中关于除正确流以外都依赖于异常流处理失败流的思虑,我认为过于绝对。
如果真这样,if else就没有用了。 我认为还是应该从发生的机率来划分:至少10%以下才能用异常流! |
|
返回顶楼 | |
发表时间:2009-01-16
czx566 写道 业务的异常的定义中关于除正确流以外都依赖于异常流处理失败流的思虑,我认为过于绝对。 如果真这样,if else就没有用了。 我认为还是应该从发生的机率来划分:至少10%以下才能用异常流! 我这里只是说对于业务层关于处理正常流程失败时,这种情况下给action层以业务异常进行通知。而对于if else也应该属于正常流程的范围。所谓执行失败,就是整个程序没法再执行下去,已经不符合业务逻辑了。这里只是着重于一种业务层执行失败后和action层的通知机制。 |
|
返回顶楼 | |
发表时间:2009-01-16
你所说的业务异常,很多都是数据的验证~ 但是还有很多非此方面的,对于这种异常,一般都有系统的异常处理策略而非统一的抛出。
|
|
返回顶楼 | |
发表时间:2009-01-16
我一直主张在开发项目前先开发一套和使用无关但是提高效率的配置管理工具,比如在开发网络通讯程序时开发一个工具用来监测网络环境,这样未来如果真正开发的时候程序跑不通,如果没有这样的工具,很难排除是网络环境造成的还是程序本身有问题.
至于异常,我有这个一个想法,开发一个小工具,打开页面能看到在过去几周时间里,整个小组开发时各类异常抛出过多少,以及哪个人的哪类异常经常抛出,按说你是不可能察看每个人代码,看看每个人抛哪些异常多少能知道开发中存在哪些问题. |
|
返回顶楼 | |
发表时间:2009-01-16
这样做是预期业务流程要么成功,要么失败。如果预期业务流程要有一个结果,不同的结果有不同的后续流程,则可以摆脱对异常的依赖,同时让所有分支在掌控之中。为什么最好不要依赖异常,因为那样会让后续的开发处在一个模糊地带。
|
|
返回顶楼 | |
发表时间:2009-01-16
czx566 写道 你所说的业务异常,很多都是数据的验证~ 但是还有很多非此方面的,对于这种异常,一般都有系统的异常处理策略而非统一的抛出。 我想说的是业务异常并非都是对数据的验证,对数据的简单验证应该在将数据传入业务层之前就处理完成,而如我说的类似判断: 当你添加一个家庭成员时,如果已经添加了父亲和母亲,那么新增加的家庭成员,如果角色为儿子,则其年龄是不应该大于父母亲,或者二者之间应该有个年龄差,这类需要很复杂的业务逻辑判断的数据校验,是不可能做到表现层去的,而应该在业务层进行校验,一旦校验失败,作为异常抛出,才属于业务异常(当然,你也可以选择其他机制,我这里所说的应该也是一种声明性异常)。 同时我也认为这应该是系统异常处理策略的一部分。 |
|
返回顶楼 | |
发表时间:2009-01-16
引用 例如在修改一个用户信息时,传递用户的年龄(age)不 应该大于其父母亲的年龄,因此在service层中必然会做一个和父母亲年龄作比较的业务判断, 一旦判断失败,在通常的处理中是返回一个标识,而我认为在业务中我们应该只关心正确流程, 也就是说整个程序没有执行失败的返回路径,作为替代,我们定义一种异常,向上层抛出,以标 识的失败,这种异常就是我们称为的业务异常。 这种也当异常,太奢侈了吧,至多验证一下,提醒用户就算了 |
|
返回顶楼 | |
发表时间:2009-01-16
gafking 写道 这样做是预期业务流程要么成功,要么失败。如果预期业务流程要有一个结果,不同的结果有不同的后续流程,则可以摆脱对异常的依赖,同时让所有分支在掌控之中。为什么最好不要依赖异常,因为那样会让后续的开发处在一个模糊地带。 我赞成你的说法,但是预期的失败情况总得告诉调用者啊,你可以选择返回特定的描述码,但是一旦这种预期的失败情况很多,那调用者是根据你返回的失败描述码进行if else判断呢,还是使用switch机制呢,还不如定义一种自己的异常,调用者只需要判断自己捕获到业务异常,然后通过业务异常码就可以知道是怎样的一种业务失败。 |
|
返回顶楼 | |
发表时间:2009-01-16
unsid 写道 我一直主张在开发项目前先开发一套和使用无关但是提高效率的配置管理工具,比如在开发网络通讯程序时开发一个工具用来监测网络环境,这样未来如果真正开发的时候程序跑不通,如果没有这样的工具,很难排除是网络环境造成的还是程序本身有问题. 至于异常,我有这个一个想法,开发一个小工具,打开页面能看到在过去几周时间里,整个小组开发时各类异常抛出过多少,以及哪个人的哪类异常经常抛出,按说你是不可能察看每个人代码,看看每个人抛哪些异常多少能知道开发中存在哪些问题. 呵呵 这位大哥说的我十分赞同。 |
|
返回顶楼 | |