最近开发的项目中,dao,service,controller中的类都是throws Excepiton,但在方法中为什么还要catch后再抛,想知道SSM开发web应用详细的异常处理机制
认证高级PHP讲师
以下僅為個人做法,僅供參考。
Controller层:在没有AOP或Filter介入的情況下,個人認為這裡的所有方法內產生的異常都要處理;
Controller
AOP
Filter
DAO层:这一层的异常多为SQL异常,一般抛给Service層處理;
DAO
Service
Service層:如果認為該異常無需調用者介入處理,則在Service內部處理,反之則拋給調用者處理(其實就是甩鍋……);
只有一種情況下,我才會catch之後再throw一個Exception,就是catch了A异常,然后抛出了B异常,这通常跟使用AOP统一处理异常搭配,例如:catch了A,B,C异常,统一交给AOP的D異常處理器處理。
Exception
個人認為catch異常的原則是當程式碼對期待的異常有業務處理需要的時候才需要catch異常,例如SQL錯誤的時候需要回滾事務之類的,其它基本上沒必要catch異常,讓最外層業務進行統一處理異常即可。
幾個個人建議:
(1)檢查型異常轉為RuntimeException,抛这个一般认为是bug(2)自定义异常(业务异常)继承自RuntimeException,设计自定义异常的时候要考虑异常抛出的时候能够通过日志信息快速重现发生异常的场景。(3)关于是否抛出异常,一般来说如果需要调用方知晓可能会发生业务异常,并能处理的,就抛。如果调用方无法处理的异常,就catch掉。简而言之就是不要“甩锅”。(4)强烈不建议catch Exception,這種程式碼在發生異常的時候很難快速定位問題。
RuntimeException
catch Exception
建議Dao层,直接往上抛异常(一般都是数据库的运行时异常),Service層因為是暴露給其它應用的,並且會有很多業務信息需要傳遞給上層的調用者,所以這裡有兩種方式
Dao
透過拋出業務異常來,告知調用方具體的業務異常資訊/系統異常資訊(系統異常,上層可能不會關注)
Service中保证不会出现异常,并且返回一个Result给上层,Result裡麵包含的資訊有:這次呼叫是否成功,如果失敗會有一些業務資訊
Result
所以不用層層都去抓異常,如果要處理就在Service中處理(不管是單應用還是以後的服務化),具體在service中是以上述的哪種方式,具體看團隊的選擇了
大體的業務流程我們是用try{}catch{}來控制,還是用if()來控制
以下僅為個人做法,僅供參考。
Controller
层:在没有
AOP
或Filter
介入的情況下,個人認為這裡的所有方法內產生的異常都要處理;DAO
层:这一层的异常多为SQL异常,一般抛给
Service
層處理;Service
層:如果認為該異常無需調用者介入處理,則在Service內部處理,反之則拋給調用者處理(其實就是甩鍋……);
只有一種情況下,我才會catch之後再throw一個
Exception
,就是catch了A异常,然后抛出了B异常,这通常跟使用AOP
统一处理异常搭配,例如:catch了A,B,C异常,统一交给AOP
的D異常處理器處理。個人認為catch異常的原則是當程式碼對期待的異常有業務處理需要的時候才需要catch異常,例如SQL錯誤的時候需要回滾事務之類的,其它基本上沒必要catch異常,讓最外層業務進行統一處理異常即可。
幾個個人建議:
(1)檢查型異常轉為
RuntimeException
,抛这个一般认为是bug(2)自定义异常(业务异常)继承自
RuntimeException
,设计自定义异常的时候要考虑异常抛出的时候能够通过日志信息快速重现发生异常的场景。(3)关于是否抛出异常,一般来说如果需要调用方知晓可能会发生业务异常,并能处理的,就抛。如果调用方无法处理的异常,就catch掉。简而言之就是不要“甩锅”。
(4)强烈不建议
catch Exception
,這種程式碼在發生異常的時候很難快速定位問題。建議
Dao
层,直接往上抛异常(一般都是数据库的运行时异常),Service
層因為是暴露給其它應用的,並且會有很多業務信息需要傳遞給上層的調用者,所以這裡有兩種方式透過拋出業務異常來,告知調用方具體的業務異常資訊/系統異常資訊(系統異常,上層可能不會關注)
Service
中保证不会出现异常,并且返回一个Result
给上层,Result
裡麵包含的資訊有:這次呼叫是否成功,如果失敗會有一些業務資訊所以不用層層都去抓異常,如果要處理就在
Service
中處理(不管是單應用還是以後的服務化),具體在service中是以上述的哪種方式,具體看團隊的選擇了大體的業務流程我們是用try{}catch{}來控制,還是用if()來控制