2013-08-05 22 views
0

我正在實現基於Spring MVC的Web應用程序,並圍繞DDD概念進行組織。目前我嘗試實現票務預訂功能。客戶可以看到特定事件可用的票數。然後,他可以輸入要保留的票數並提交表單。由調用負責註冊的應用服務的控制器接收請求。應用服務邏輯如下:來自應用服務層的報告錯誤

  1. 驗證傳入的參數:
    • 1A。檢查具有給定ID的事件是否存在
    • 1B。檢查是否可售門票數量允許保留
  2. 如果驗證通過,以繼續進行註冊;否則,報告錯誤。

我對報告驗證錯誤的正確方法有一些懷疑 - 特別是對於第1B點。門票數量不允許預訂的情況並不常見。客戶可以看到與數據庫中當前票數不完全同步的票數(最終一致性) - 其他人可以同時預訂一些票。

起初,我還想着報告通過拋出一些特定的例外這個問題。但是,我可以想到其他幾個有問題的情況,並且每個人都有一個例外情況聽起來不太好。

我正在考慮被扔一個型含錯誤代碼的異常的另一種選擇。但是,我不知道如何正確處理Spring MVC中的這種情況。

這些問題的最佳實踐是什麼?你如何在你的MVC應用程序中處理它們?任何建議不勝感激。

回答

1

我認爲這些是無法恢復的業務限制brokens。

我目前的解決方案是異常層次結構。

public abstract class UncheckedApplicationException extends RuntimeException { 

    //omitted factory methods and constructors 
    public abstract String getStatusCode(); 

    public abstract String getI18nCode();//ignore this if you don't need i18n  

    public abstract String[] getI18nArgs();//ignore this if you don't need i18n 
} 

任何自定義異常擴展了這一個。我認爲這可能避免這樣的代碼:

try { 
    //invoke your application service 
} catch (InsufficientInventoryException e) { 
    statusCode = INSUFFICIENT_INVENTORY; 
} catch (ExpriedPriceException e) { 
    statusCode = EXPIRED_PRICE; 
} catch (NoSuchProductException e) { 
    statusCode = NO_SUCH_PRODUCT; 
} catch (Exception e) { 
    statusCode = UNKNOWN; 
} 

控制器代碼片段:

try { 
    //invoke your application service here 
    statusCode = SUCCESS; 
    message = messageSource.getSuccess(locale)); 
} catch (UncheckedApplicationException e) { 
    statusCode = e.getStatusCode(); 
    message = messageSource.getMessage(e, locale)); 
} catch (Exception e) { 
    statusCode = UNKNOWN; 
    message = messageSource.getUnknownError(e, locale)); 
} 
//add statusCode & message to modelAttribute 

您可以使用@ExceptionHandler減少樣板的try-catch代碼,如果你的控制器組織得很好(但相當困難) 。

另一個原因使用Excepton是應用服務經常被用來劃定事務邊界。如果要回滾,必須拋出異常。

+0

感謝,其他有趣的選擇可能是從MessageSource的地方異常唯一的消息代碼,並在以後檢索它(這個代碼)。 –