2013-06-03 22 views
4

我知道有很多已經被周圍的異常處理的討論,不過我需要一些專門針對我的情況的意見。的Java拋出異常VS返回響應漁獲

我目前工作的一個Spring MVC應用與Controller->Services->DAO層。服務類主要捕獲兩種例外HibernateExceptionIOException

HibernateException因爲服務需要執行回滾,如果事務沒有成功,並且IOException,因爲它是一個未經檢查的異常,需要被捕獲或拋出,我更喜歡第一個選項。

現在會是什麼處理這些進一步向上堆疊中的一個更好的辦法:

  1. 我應該重新拋出這些異常的控制器和控制器的 ExceptionHandler發送一個HTTP錯誤代碼500
  2. 或在catch塊創建正常JSON response對象,設置status=failure和相應的錯誤信息,這回控制器?
+2

你應該和你的觀點去1. –

+0

'在技​​術上,IOException'不是一個未經檢查的異常;你在這裏意味着什麼? – fge

+1

如果不能處理它們,我會捕獲檢查的異常並將它們重新包裝爲自定義運行時異常。 –

回答

9

異常處理convensions:

有一種說法是,處理異常最好的方法就是不處理它!

對於controller<->service<->daoSpring的慣例,Exception處理機制被稱爲Bubble up。在daoservice層發生任何異常,您應該彈出它到controller層(通過在dao和服務層的方法簽名中添加throws XXXException是最常見的方式)。只有controller層應處理異常。

這是一個很好的教程,你可以如何handle exceptions for REST with spring

發送HTTP狀態碼500或JSON對象與狀態:

聽起來像是你用Spring MVC編寫API。看,當你編寫API時,你應該遵循適當的約定。全球認可的是,對於發送內部服務器錯誤,您發送的HTTP響應代碼爲500,這意味着內部服務器錯誤。

在這種情況下,您應該不發送JSON響應的原因有多種。其中一個主要原因是您的API客戶端的隱含假設。那就是代碼爲200的HTTP響應與JSON對象意味着每件事情都正常。因此,客戶端業務邏輯可能反映出最終錯誤的假設。

在這裏你可以看到一些API錯誤代碼約定一些知名機構:

+0

感謝您的富有洞察力的迴應。我正在開發一個主要使用Ajax的jQuery客戶端的Spring MVC應用程序。我認爲無論是否是api或不正確的錯誤處理對於在整個應用程序中保持一致非常重要。如果web服務執行成功地發送HTTP響應200,並且在發生異常的情況下發送適當的HTTP錯誤響應代碼,那麼我將遵循您的建議。 – user1140448

+0

很高興聽到...... :) –

2

我認爲你還沒有到目前爲止還沒有創建一個客戶端,因此可以爲自己挑選100%。

如果是這樣,我也建議使用1,因爲使用正確的狀態代碼可以在API中發揮很大的作用,以及它是解決您的問題的非常簡單的方法。你可以爲你的錯誤處理編寫一些整潔的代碼。 爲什麼你應該用你的第一個點的另一個重要原因是因爲你可以很容易地重新使用的錯誤處理,其他API,資源或web應用。

例如,一個包含所有錯誤的枚舉,以及您認爲它們是什麼狀態碼,還可以包含您希望它們的日誌級別。

public enum ExceptionMapping { 
IllegalArgumentException(IllegalArgumentException.class, 400, LogLevel.ERROR), 

如果你的目標是建立未知客戶端整齊API我會推薦閱讀更多關於REST級別3(http://martinfowler.com/articles/richardsonMaturityModel.html),您包括超媒體鏈接創建API,它允許客戶端「瀏覽」你的全API。這對客戶來說是更多的工作,因爲他們必須更聰明,但它可以爲您提供非常好的功能,例如在客戶端甚至沒有注意到的情況下破壞大部分API。

+0

+1爲富有洞察力的鏈接。我已經在jquery客戶端上工作了,但是由於我一手在服務器和客戶端上工作,所以仍然可以進行更改。 – user1140448