Guice @SessionScoped注释导致与Shiro HttpSession的IllegalArgumentException

时间:2013-11-26 10:47:12

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

我有一个Apache Wicket 1.5应用程序,它使用Shiro来保证安全性,Guice用于依赖注入。 它的大多数页面都是无状态的,但我的一些模型对象(用户数据,当前菜单状态......)需要在同一会话中的所有请求中保持一致。所有这些对象都有逻辑(大多数使用远程EJB3接口访问数据库的简单finder方法)和状态,所有这些都实现了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对象来存储会话中的对象,而Shiro HttpSession实现无法处理。但奇怪的是,所有@SessionScoped类都不会发生此异常,但肯定会出现多个异常。

我一直在网上搜索疯狂,寻找一个想法我能做什么 - 某种方式迫使Guice使用字符串键,一些其他方法使HttpSession更兼容,任何东西 - 但我似乎无法找到任何有用的信息。另外,根据我的搜索结果判断错误消息,我似乎是这个星球上唯一一个甚至有这个问题的人...

有没有办法让这项工作?或者我在这里做错了什么?

1 个答案:

答案 0 :(得分:1)

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

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

你可以改变吗

@Inject
public UserService users;

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

为什么会这样?

  1. SessionScoped个对象仅可以访问GuiceFilter.doFilter() ,因此如果您混合使用范围,它可能最终会出现在某些运行时异常中。特别是,当您将Stage更改为Production或将某些单身人士设置为急切加载时。您可以了解更多here。混合Providers

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

  4. 希望,会有所帮助。