java - Guice @SessionScoped 注释导致 IllegalArgumentException 与 Shiro HttpSession

标签 java guice shiro java-ee-5 wicket-1.5

我有一个 Apache Wicket 1.5 应用程序,它使用 Shiro 来保证安全,并使用 Guice 来进行依赖注入(inject)。 它的大部分页面都是无状态的,但我的一些模型对象(用户数据、当前菜单状态……)需要在同一 session 中的所有请求中保持一致。所有这些对象都具有逻辑(主要是使用远程 EJB3 接口(interface)访问数据库的简单查找器方法)和状态,并且它们都实现了 Serializable。

这里有一个简短的摘录,应该可以传达这个想法:

@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.

显然,Guice 似乎使用一些自定义的 Key 对象来存储 session 中的对象,而 Shiro HttpSession 实现无法处理。不过,奇怪的是,并非所有 @SessionScoped 类都会发生此异常,但肯定不止一个。

我一直在疯狂地搜索网络,寻找我能做些什么的想法 - 一些强制 Guice 使用字符串作为键的方法,一些其他使 HttpSession 更兼容的方法,任何东西 - 但我似乎无法找到任何有用的信息。另外,从我对错误消息的搜索结果来看,我似乎是这个星球上唯一遇到这个问题的人......

有什么办法可以实现吗?还是我在这里做错了什么?

最佳答案

好吧,这个问题很难回答,但我试着给你一些选择......

您的错误来自前期检查...所以,我假设您的应用程序甚至没有启动,对吧?那么您很可能正在使用生产阶段,或者急切地创建了一些绑定(bind),并且该对象引用了 Session 范围内的另一个对象,这就是问题所在。因此,现在您应该将所有 SessionScope 直接注入(inject)更改为 Providers 注入(inject),如本例所示:

你能改变吗

@Inject
public UserService users;

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

为什么会这样?

  1. SessionScoped 对象只能在 GuiceFilter.doFilter() 中访问,因此如果您混合作用域,它可能会在某些运行时结束异常(exception)。特别是,当您将 Stage 更改为 Production 或将一些 Singleton 设置为急切加载时。您可以了解更多here .混合使用 Scopes

  2. 时,最好使用 Providers
  3. 问题可能是 Subject 仅在 ShiroFilter.doFilter() 内部绑定(bind) check my post .然后,如果你在外面,假设 GuiceFilter 那时可能没有 Subject 绑定(bind)。再次尝试使用 Providers

希望能有所帮助。

关于java - Guice @SessionScoped 注释导致 IllegalArgumentException 与 Shiro HttpSession,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20214904/

相关文章:

java - Guice 初学者 - 如何绑定(bind)具体类 - 单例?

java - ApacheShiro - 使用 Storm 路径的 SSO

java - FakeRequest 类型 Promise 的结果

java - 当 portlet 不存在时 Liferay 提醒用户

java - Mergesort这个合并函数占用O(1)空间还是O(n)空间?

java - HK2 相当于 Guice 中的 @Provides for Jersey 2

java - android:内部文件读取

java - 在 Guice 中绑定(bind) HashMap 实例

spring - 如何保护 Grails 中的所有 REST 请求和响应

java - Java 1.8.0_211更新后Shiro鉴权异常