2013-11-26 102 views
4

我有一個Apache Wicket 1.5應用程序,使用Shiro作爲安全性,Guice作爲依賴注入。 其大部分頁面都是無狀態的,但我的一些模型對象(用戶數據,當前菜單狀態...)需要在同一個會話中的所有請求中保持一致。所有這些對象都具有邏輯(大多是使用遠程EJB3接口訪問數據庫的簡單查找方法)和狀態,所有這些對象都實現了Serializable。Guice @SessionScoped註釋導致與Shiro HttpSession IllegalArgumentException

下面是一個簡短摘錄要傳達的理念:

@SessionScoped 
public class UsersImpl implements Users, Serializable { 

    private static final long serialVersionUID = 8841809043461673585L; 
    private final Logger log = LoggerFactory.getLogger(UsersImpl.class); 

    @Inject 
    public UserService users; 

    @Inject 
    public RoleService roles; 

    private UserDTO currentUser; 

    public UserVO findUserByUser(UserVO user) { 
     UserDTO userDto = null; 
     try { 
      userDto = users.findUserByUser(user.toUserDTO()); 
     } catch(Exception e) { 
      log.error("Error finding user:"+user.id, e); 
     } 
     return userDto != null ? new UserVO(userDto) : null; 
    } 

(...) 

} 

我開發和單元測試使用@Singleton(爲簡單起見)類,和一切工作正常這種方式,但我得到這樣頻繁出錯,現在,我已經切換到@SessionScoped生產:

Guice provision errors: 
1) Error in custom provider, org.apache.shiro.session.InvalidSessionException: 
    java.lang.IllegalArgumentException: 
    HttpSession based implementations of the Shiro Session interface requires attribute keys to be String objects. The HttpSession class does not support anything other than String keys. 

顯然,吉斯似乎用一些自定義的關鍵對象的對象存儲在會話,四郎的HttpSession的實現不能處理這個問題。奇怪的是,儘管如此,對於所有的@SessionScoped類都不會發生這種異常,但肯定是不止一種。

我一直在尋找瘋狂的網絡,尋找一個想法,我可以做些什麼 - 強制Guice使用字符串鍵,其他方式使HttpSession更兼容,任何東西 - 但我不能似乎找到任何有用的信息。另外,根據我的搜索結果判斷錯誤信息,我似乎是這個星球上唯一一個甚至有這個問題的人...

有沒有什麼辦法可以使這項工作成爲可能?或者我在這裏做錯了什麼?

+0

你如何初始化'Shiro'?通過安裝'ShiroModule'? –

+0

我安裝了'ShiroAopModule'和一個自定義擴展了'ShiroWebModule'的東西,並且擁有了一切,否則你會把它放在'shiro.ini'中。這也將'SessionScoped.class'綁定到'ShiroSessionScope'。 'UsersImpl'沒有單獨的模塊 - ''用戶''的界面用'@ ImplementedBy'註解。 – weltraumpirat

+0

整個設置工作正常,如果我使用'@ Singleton'而不是'@ SessionScoped':所有注入都可以工作,並且整個應用程序運行時沒有錯誤 - 當然,只限於單個用戶。 – weltraumpirat

回答

1

嗯,這個問題很難回答,但我儘量給你一些選項...

你的錯誤是從前期檢查...所以,我想你的應用程序甚至沒有開始,對不對?那麼你很有可能在使用Production階段或者有一些綁定熱切地在創建的那個對象指向另一個在Session範圍內,這是問題所在。所以,現在你應該改變所有的SessionScope直接燃油噴射技術提供商注射如本例:

你能不能改變

@Inject 
public UserService users; 

@Inject 
public Provider<UserService> userProvider; //and call userProvider.get() when you will need it? 

爲什麼會這樣?

  1. SessionScoped對象只有whitin GuiceFilter.doFilter()如此接近,如果你混合示波器它可以在一些運行時異常結束。特別是,當您將Stage更改爲Production或將某些單例設置爲急切加載時。您可以瞭解更多here。混合Scopes

  2. 的問題時,可能是該Subject只是內部ShiroFilter.doFilter()check my post結合它的使用方法Providers好的做法。那麼,如果你在外面讓我說GuiceFilter當時可能沒有Subject約束。再次嘗試使用Providers

希望,會有所幫助。

+0

謝謝,我會嘗試提供商。雖然當我打電話的時候發生異常 - 應用程序開始沒有問題。 – weltraumpirat

+1

經過一番大規模的嘗試並將我的頭撞在鍵盤上後,我想我可能已經找到了整個問題的根源:它看起來像是由一個陳舊的依賴引起的(我使用ehcache 2.7.4來存儲會話,並在我的模塊之一,ehcache-core仍然是一個更老的版本)。現在測試整個應用程序太累了,但fwiw:非提供程序版本似乎工作正常,至少從我更新依賴關係以來看到的。謝謝你的幫助,明天我會有明確的答案。 – weltraumpirat

+0

事實證明,原來的錯誤確實消失了,現在我已將所有依賴項更新爲最新版本。然而,你對提供者的建議a)幫助我走上了正確的軌道,並且b)偶然地修復了我正在努力的另一個問題。因此,我會接受你的答案,即使它沒有完全解決問題。再次感謝您的幫助! – weltraumpirat