在Java LoginModules之间传递信息(通用映射问题)

时间:2011-06-30 13:37:31

标签: java generics map jaas

我目前正在尝试编写一些LoginModule以使用户能够登录Java应用程序。这是我的.java.login.config文件:

"Java Application" {
    path.to.login.module.PamLoginModule   sufficient;
    path.to.login.module.OtherLoginModule sufficient;
};

因此,如果PamLoginModule失败,我想将信息传递给OtherLoginModule。这样,OtherLoginModule不必再次询问用户名和密码。所以我猜这是sharedize()函数中的sharedState Map:

initialize(Subject subject, CallbackHandler callbackHandler, 
           Map<String,?> sharedState, Map<String,?> options) 

问题是您无法将内容放入sharedState映射中。如果我这样做:

sharedState.put("key", value); // Value is a string

编译器抱怨:

path/to/login/module/PamLoginModule.java:48: put(java.lang.String,capture#833 of ?) in java.util.Map<java.lang.String,capture#833 of ?> cannot be applied to (java.lang.String,java.lang.String)
    this.sharedState.put("key", value);

我找到了解决这个问题的方法,但我想知道正确的方法是什么。

首先,我可以使用java 1.4.2版本的initialize:

initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) 

这样我只会收到通用地图,我可以将Map对象转换为Map

Map<String,Object> this.sharedState = (Map<String,Object>)sharedState;

问题是我仍然得到未经检查的强制转换异常。现在,我知道创建LoginModule接口的人并不愚蠢,所以我想知道为什么他们将sharedState映射设为Map<String,?>而不是Map<String,Object>。另外,有没有更好的方法将内容放入sharedState映射?

谢谢!

2 个答案:

答案 0 :(得分:1)

  

我想知道为什么他们这样做了   sharedState将Map<String,?>映射为   反对Map<String,Object>

这正是我想知道的。 我想使用?的目的是接受任何事情(我真的没有看到另一种解释),所以使用Object将是完全正确和标准的。

如果你在这里发帖,我想你不能问这是谁用这种方式编码(用?)知道原因。 因此,您应该调查一下相关的类/方法,以发现?是否真的有意义和特定用途。否则,您应该将其设为<String, Object&gt;。

我个人从未见过当前使用过,除非?被指定为<? implements MyInterface><T extends MySuperClass>。在第一种情况下,无论如何都应该能够Map<String, MyInterface>得到相同的结果。

很抱歉,如果我没有具体的答案,但我希望这可以帮到你!

答案 1 :(得分:1)

如果您查看Java SDK中的LoginModule实现,他们会将这些地图保存到没有泛型信息的本地字段中,即普通地图。在代码中,他们将对象放在那里(至少在用户通过身份验证时)。因此,在LoginModule界面中使用问号必须是设计错误。