2013-02-06 171 views
7

我們在我們的應用程序中使用JSF,Spring和JPA。我們正在努力簡化我們項目的異常處理策略。Spring/JPA/JSF異常處理策略

我們的應用程序的體系結構是象下面這樣:

UI(JSF) - >管Bean - >服務 - > DAO

我們使用異常翻譯後豆處理器,用於DAO層。這是在Spring應用程序上下文文件中配置的。

<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" /> 

Spring將所有數據庫異常包裝爲'org.springframework.dao.DataAccessException'。我們沒有在DAO Layer中進行其他異常處理。

我們的策略來處理異常象下面這樣:

表示層:

Class PresentationManangedBean{ 

try{ 
     serviceMethod(); 
    }catch(BusinessException be){ 
     // Mapping exception messages to show on UI 
    } 
    catch(Exception e){ 
     // Mapping exception messages to show on UI 
    } 

} 

服務層

@Component("service") 
Class Service{ 

@Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = BusinessException.class) 
public serviceMethod(){ 

    try{ 

     daoMethod(); 

    }catch(DataAccessException cdae){ 
     throws new BusinessException(); // Our Business/Custom exception 
    } 
    catch(Exception e){ 
     throws new BusinessException(); // Our Business/Custom exception 
    } 
} 

} 

DAO層

@Repository("dao") 
Class DAO{ 

public daoMethod(){ 
    // No exception is handled 
    // If any DataAccessException or RuntimeException is occurred this 
    // is thrown to ServiceLayer 
} 

} 

問: 我們只是想確認上述做法是否按照最佳做法。如果沒有,請向我們建議處理異常情況的最佳方法(使用交易管理)?

+0

我也想遵循這個認識,但是當我捕捉到異常並拋出我們的自定義異常時,我的異常處理程序不會出現這種情況。 Spring將我的異常包裝到'org.springframework.transaction.TransactionSystemException'中。這是我的問題http://stackoverflow.com/questions/28295684/unable-to-wrap-dao-exception-in-service-layer-using-spring-mvc。我如何解決我的問題? –

回答

1

這種方法對我來說很好,我們在我們的項目中使用了同樣的方法。

維奈

0

你的做法是與Spring框架的建議非常一致,也避免了大量的滲透在你的應用層檢查異常。

1

我使用不同的方法:

- 我不趕春的DAE在DAO。我讓他們流向Controller(JSF託管bean)。

- 在控制器中,我捕獲任何異常(只有一個「catch」)。

-I調用一個自定義的「handleException」方法,它接收在參數中捕獲的異常。

- 此異常處理程序檢查(例如,用「if-then-else」語句)參數是什麼類型的異常,並根據這種異常向用戶顯示消息。在我的情況下,我尋找消息顯示在一個屬性文件中,其中消息的關鍵字(以及參數,如果有的話)是異常的屬性(我把它放在那裏,當我扔它)。特別是,如果您想以特殊方式處理DAE,可以在此異常處理程序方法中爲其添加「if」分支,並根據需要執行任何操作。

我認爲這種方法更好,更清潔,因爲您只需要在一個點上處理異常,而且您不必在每個級別放置如此多的「throws-try-catch」,只需在Controller中JSF)。

當然,如果您想在特定情況下執行某些業務邏輯,而不是向用戶顯示消息,則可以在服務中使用「try-catch」。另外,如果你不想在控制器中處理Spring DAE,你可以將它包裝成自己的業務異常並重新拋出。但是在服務層中,而不是在DAO中。

希望此回答有幫助。

0

也許你可以分開BusinessException和BusinessRuntimeException, 當你捕獲BusinessException引發BusinessException但是當你得到異常時仍然拋出相同的BusinessException。嘗試將它們分開。順便說一句,爲什麼當您捕獲BusinessException時拋出相同的異常?

+0

感謝您的評論erhan ...我會看看並回復你 –

0

我在做一些研究,因爲我自己對此感到困惑。不過,我有一個稍微不同的看法。

原理是在多層上拋出和捕獲異常在性能和代碼可讀性方面代價很高。癥結在於服務方法不應該拋出異常。相反,他們應該總是返回一個應該封裝狀態,消息和輸出實體的響應。

但是,如果Controller調用多個服務方法並嘗試基於響應組合繪製,則可以將其放入try catch塊並處理異常。

有了這個邏輯,它可以同等地處理衝刺mvc和rest mvc。讓我知道你的想法。

Class PresentationManangedBean{ 
     try { 
     Response resp1 = serviceMethod(); 
     if (resp1.getStatus().equals("SUCCESSFUL")) 
      // handle UI painting logic. 
     else 
      // handle error for UI 
     Response resp2 = serviceMethod2(); 
     if (resp.getStatus().equals("SUCCESSFUL")) 
      // handle UI painting logic. 
     else 
      // handle error for UI 
     // handle resp1 and resp2 to paint UI. 
    } catch (Exception e) { 
      // handle error for UI 
    } 
} 

1)服務應該處理所有異常。控制器不應該處理任何異常。 2)