2017-07-11 53 views
0

在我們的應用中,所有的REST API的形式爲:訪問數據

HTTP:// {上下文}/{PRODUCT_ID}/{rest_url_path}

我必須通過從數據庫中獲取product_id的ProductDetails來驗證Spring Security Filter/SpringMVC攔截器中的{product_id}。 ProductDetails將在Spring控制器/服務類中使用。

我不想在控制器/服務中再次獲取ProductDetails。所以我想爲RequestScope某處存儲ProductDetails對象。

我有3種方法。但每個人都有自己的優點和缺點。請讓我知道哪一個更好。另外建議任何替代方法。

方法-1:

保存請求屬性內的ProductDetails對象。 內部控制器,我可以很容易地得到HttpRequest。內部服務,我可以得到HttpRequest通過:

@Autowired 
HttpServletRequest request; 

RequestAttributes attribs = RequestContextHolder.getRequestAttributes(); 
HttpServletRequest request = null; 
if (attribs instanceof ServletRequestAttributes) { 
    request = ((ServletRequestAttributes) attribs).getRequest(); 
} 

但我不希望有內部服務的HTTP請求的依賴做出代碼WebLayer邏輯更加獨立。

方法2:

使用任何在內存中緩存基於product_id存儲ProductDetails

但是,這我覺得只有殺了這個用例。增加緩存不必要的依賴關係。

方法-3:

貯存於ThreadLocal變量來存儲請求範圍數據的對象。 但不知道這是否正確。

讓我知道,一個有效的辦法來解決這個問題

回答

0

你提到的第一種方法是訪問兩個過濾器,即使你要注入的HttpServletRequest的SpringController依賴控制器相同的數據更有效的方式。

如果數據是非常用戶特定的,就像其他用戶在這種情況下無法訪問這些數據一樣,您應該使用ThreadLocal。

+0

欲瞭解更多信息,你可以檢查https://stackoverflow.com/questions/35444633/spring-how-to-pass-objects-from-filters-to-controllers。這是一種類似的用例。 –

+0

按照上面這個線程,我猜'ThreadLocal'似乎很有效率。還有關於使用'RequestScope Bean'的說法。這看起來更有效率。我必須試一試 – Tushar

0

第一個和第三個適用於您的問題陳述,但第一個更優雅,因爲數據將僅存儲在當前請求範圍內,並在服務器發送響應時自動丟失。你也可以使用threadLocal,但你必須謹慎,如果你忘記刪除它將在使用線程池的環境中停留的對象。