[英]How to retrieve a session scoped managed bean in a PhaseListener?
我在设置授权监听器(实现PhaseListener)以管理身份验证和自动化方面遇到了麻烦。
更具体地说,我设置了一个名为SessionBean的会话范围bean:
@ManagedBean
@SessionScoped
public class SessionBean{
private String loggedUser;
public SessionBean(){
logger.info("Sono nel costruttore di SessionBean()");
}
public String login(){
....
}
...
}
在我的sun-web.xml中:
<managed-bean>
<managed-bean-name>SessionBean</managed-bean-name>
<managed-bean-class>it.uniroma3.acme.auction.bean.SessionBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
在login()中,我对用户名/密码进行控制,如果成功,我设置“loggedUser”。
我的AuthorizationListener是:
public class AuthorizationListener implements PhaseListener {
private String currentUser;
private SessionBean sessionBean;
public void afterPhase(PhaseEvent event) {
SessionBean sessionBean = (SessionBean)event.getFacesContext().getExternalContext().getSessionMap().get("SessionBean");
String currentUser = sessionBean.getLoggedUser();
if (sessionBean != null) {
...
String currentUser = sessionBean.getLoggedUser();
}
else {
...
}
}
...
}
在sun-web.xml中:
<!-- Authentication and authorization block starting -->
<lifecycle>
<phase-listener>AuthorizationListener</phase-listener>
</lifecycle>
<navigation-rule>
<from-view-id>/*</from-view-id>
<navigation-case>
<from-outcome>loginPage</from-outcome>
<to-view-id>login.jsf</to-view-id>
</navigation-case>
</navigation-rule>
<!-- Authentication and authorization block ending -->
但我收到一个空的pointe sessionBean.getLoggedUser()。 因此,当AuthorizationListener检查用户时,仍未创建SessionBean。 这就是我添加“如果SessionBean不存在,创建它并将其放在SessionMap中”的原因,但仍然无效。
我不是被迫使用这种方法进行身份验证和授权,但我需要的是避免使用“session.setAttribute(”username“,username)。所以任何其他策略都会真的是apreciated。谢谢,Andrea
编辑:正如BalusC建议的那样,我编辑了afterPhase方法。 始终为null的SessionBean仍然存在问题。
@ManagedProperty
仅适用于@ManagedBean
类。 您的PhaseListener
不是。
您需要从会话映射中手动获取它。
SessionBean sessionBean = (SessionBean) event.getFacesContext()
.getExternalContext().getSessionMap().get("SessionBean");
请注意,它在第一个HTTP请求时仍可以为null
。
但是,常见的方法是为作业使用servlet Filter
,而不是使用PhaseListener
。 会话范围的托管bean可用作会话属性。
SessionBean sessionBean = (SessionBean) session.getAttribute("sessionBean");
在这里,你的代码,在你的PhaseListener,你不知道在哪儿阶段正是你所执行的代码,你应该打电话给你的托管bean。 您应该在AuthorizationListener
覆盖方法getPhaseId()
中的RESTORE_VIEW
阶段中执行此操作。 请参阅以下内容:
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
如果托管bean仍为null,则删除托管bean注释,在faces_config
注册它,并在阶段侦听器中使用此帮助器方法来调用托管bean:
public static Object resolveExpression(String expression) {
FacesContext ctx = FacesContext.getCurrentInstance();
Application app = ctx.getApplication();
ValueBinding bind = app.createValueBinding(expression);
return bind.getValue(ctx);
}
要在阶段后方法中调用它,请使用:
public void afterPhase(PhaseEvent event) {
SessionBean sessionBean =(SessionBean)resolveExpression("#{SessionBean}");
String currentUser = sessionBean.getLoggedUser();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.