问题描述
<div class="iteye-blog-content-contain" style="font-size: 14px">做了几个web项目了但是对exception没有一个标准的写法,欢迎大家讨论下</div>
解决方案
这是我之前收集整理的异常设计原则(Effective Java):只为异常条件使用异常。也就是说,不要为控制流使用异常,比如,在调用 Iterator.next() 时而不是在第一次检查Iterator.hasNext() 时捕获 NoSuchElementException 。 为可恢复的条件使用检查型异常,为编程错误使用运行时异常。这里,Bloch 回应传统的 Sun 观点 —— 运行时异常应该只是用于指示编程错误,例如违反前置条件。 避免不必要的使用检查型异常。换句话说,对于调用者不可能从其中恢复的情形,或者惟一可以预见的响应将是程序退出,则不要使用检查型异常。 抛出与抽象相适应的异常。换句话说,一个方法所抛出的异常应该在一个抽象层次上定义,该抽象层次与该方法做什么相一致,而不一定与方法的底层实现细节相一致。例如,一个从文件、数据库或者 JNDI 装载资源的方法在不能找到资源时,应该抛出某种 ResourceNotFound 异常(通常使用异常链来保存隐含的原因),而不是更底层的 IOException 、 SQLException 或者 NamingException 。 到底选择检查异常还是非检查异常??? 1、检查型异常代表关于一个合法指定的请求的操作的有用信息,调用者可能已经对该操作没有控制,并且调用者需要得到有关的通知 —— 例如,文件系统已满,或者远端已经关闭连接,或者访问权限不允许该动作。 2、非检查异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。 如果是RuntimeException一般是”你“的问题。Rod Johnson(spring之父)观点 检查异常缺点:太多代码,难以读懂的代码、异常的无休止封装、易毁坏的方法签名、检查异常对接口不一定管用(可恢复及不可恢复)。检查异常要比错误返回码好的多。如果调用代码能对异常做些切合实际的事情,请使用检查异常,如果致命的,或者调用者捕捉它没什么益处,请使用非检查异常。在包级别决定每个包将怎样使用检查或非检查异常。用文字详细说明非检查异常的决定,因为许多开发人员将预料不到该决定。使用非检查异常的唯一危险是那些异常可能没有被充分用文字加以详细说明。详细的异常说明。这是iteye很早之前讨论的 http://www.iteye.com/topic/2038?page=12http://www.iteye.com/topic/72170
解决方案二:
2楼的回复内容比较杂,我就一些实际项目案例中异常的处理给予建议,仅供参考。你的项目架构是struts2、spring、hibernate……其实做这种web应用系统的异常相对比较简单,因为应用系统目前主流也就是mvc、service、orm。hibernate使用的是unchecked exception,由HibernateException extends RuntimeException,所以你在调用hibernate方法的时候,都没有捕获这种unchecked exception。ibatis使用的是checked exception,比如说直接抛出SQLException、或者extends Exception的checked exception。所以你在调用ibatis方法的时候,都要捕获异常。对于你使用hibernate情况,很多比较优秀的框架平台在service层、controller层都不会处理。包括:springside、j-hi。既然都没捕获,那么都在struts的action一起抛出。如果你没有对异常做统一的处理,那么这些orm抛出的异常直接在你访问struts的action时,在页面中显示(这种方式对用户很不友好)。所以struts2的配置文件中有一个<global-exception-mappings>的配置。这个配置的作用就是接住这些异常,然后进行处理。有些实际系统的配置如下(截取j-hi平台的): <global-results> <result name="exceptionPage" type="dispatcher"> <param name="location">/common/exceptionPage.jsp</param> </result> </global-results> <global-exception-mappings> <exception-mapping exception="org.hi.framework.web.BusinessException" result="exceptionPage" /> <exception-mapping exception="org.acegisecurity.AccessDeniedException" result="exceptionPage" /> </global-exception-mappings>这里对业务逻辑异常、以及acegi的访问拒绝异常统一返回exceptionPage这个页面。这里仅仅是使用统一的jsp对错误进行显示。这样还是不能够满足使用者对看得懂这些异常信息。此时,可通过struts的ExceptionMappingInterceptor统一拦截。当然,业务层中自定义异常(具体是自定义checked exception、还是unchecked exception,取决于具体的情况。我个人建议自定义exception集成runtimeexception。)也可完全抛给上层的action。很多实际大型项目对于异常处理都有一套体系。比如说:定义一个异常映射表,配置异常代码与错误显示信息(显示到浏览器让客户看得懂的显示信息),然后在上层捕获异常,返回错误码,再根据异常映射表获取对应的错误显示信息,响应到struts的global result。