2016-12-04 55 views
1

這個問題更多的是關於設計和乾淨的代碼,我很難理解什麼時候應該拋出一個checked checked,或者我們應該返回一個空值並檢查在客戶端如果這個值爲空或不是。當用戶會話過期或返回空時拋出異常

據我所知,檢查異常應該用於可能發生異常情況的情況,但我們無法阻止它。另外我已經讀過,我們不應該使用異常作爲控制流。所以在我的情況下,我正在編寫一個併發的應用程序,其中很多用戶會發出請求,並且我有一個方法來檢查用戶會話是否過期(並且在10分鐘後過期),所以,我在teorically應該拋出一個異常,因爲我不能防止這種情況,但另一方面,如果這種情況每10分鐘發生一次,異常是昂貴的,也許如果我返回一個null,我做檢查客戶會更好的表現。你會在這種情況下做什麼?

這是我的方法:

@Override 
public Integer getUserIdBySessionKey(String sessionKey) { 
    User user = userSessions.get(sessionKey); 
    boolean isUserSessionValid = isUserSessionValid(user); 
    return isUserSessionValid ? user.getUserId() : null; 
} 
+1

*我有一個方法來檢查用戶會話是否過期*:然後如果會話過期,我會返回true,否則返回false。我猜你的方法實際上並沒有這樣做。發佈代碼而不是描述它。 –

+0

@JB Nizet,完成。我的問題是,到目前爲止,我返回null是會話無效,但我可以拋出一個「ExpiredSessionException」,也許是一個選項或另一個之間進行選擇不是一個大問題,但我想在最乾淨可能的方式 – fgonzalez

+1

如果有機會讓調用代碼從這種情況下恢復,那麼我會返回一個可選。另一方面,如果調用代碼不應該處理這種情況,並且只是希望在會話無效時調用全局異常處理程序,那麼我會拋出一個運行時異常。無論如何,我不會拋出一個檢查的異常。 –

回答

3

那麼當您要發送信號給調用代碼必須被考慮,而且對於它們有意義的行動是一個重要的特殊情況下使用checked異常拍攝。例如,在對用戶進行身份驗證時,密碼可能是錯誤的或帳戶已過期,因此檢查AuthenticationException或AccountExpiredException可能是合理的。客戶端代碼會捕獲這些異常並對其進行適當處理。另一方面,沒有采取合理行動或通用性不足以通用處理的情況應該是未經檢查的例外情況。任何編碼錯誤(NullPointerException,IllegalStateException,數據庫錯誤,網絡錯誤等)均屬於此類別。

所以問題是,你期望調用代碼做一些關於會話過期?如果你有一個通用的機制來處理這種情況(例如一個頂級的ServletFilter或類似的),它會捕獲這樣的異常並重定向到登錄頁面,然後使其成爲一個未經檢查的異常。如果這需要來自調用代碼的特別關注,那麼請進行檢查。

在你的情況下,我會讓它取消選中,並以頂層的通用方式處理它。

+0

那麼,從客戶端我只需要知道哪種類型的異常,以返回到客戶端適當的http錯誤(在這種情況下400 Unathorized)。如果我用運行時異常來做到這一點,我不能區分異常。所以在這種情況下,檢查的表達式可能更適合,但是我可以將它清楚,如果不是發送表達式而是發送表達式,則返回一個可選,並且如果(optional.isPresent)返回Http.Unathorized,則對客戶端執行檢查,對不對? – fgonzalez

+1

您可以創建會擴展RuntimeException的SessionExpiredException。這會使得它成爲一個未經檢查的例外,您可以在頂層捕獲並適當地處理(返回400)。無需創建檢查的異常。 – Lucian

+1

順便說一句,返回null或狀態碼不是Java處理異常情況的方式。它適用於C(或其他沒有異常處理機制的語言),但不適用於Java。 – Lucian