Jsf 在每次页面刷新时调用会话范围的托管Bean构造函数
我正在使用会话范围的托管bean来处理JavaEE应用程序中的登录。在我对用户进行身份验证之后,用户对象保存在这个会话bean中。但是,在刷新页面之后,会话bean值就消失了 我正在调试代码,结果是在页面刷新时再次调用会话范围的托管bean的构造函数,因此使用新用户初始化用户对象。我想这不是一个正常的行为,因为它应该在会话中保留,不是吗 我正在发布登录管理bean的一些部分,包括参数和登录方法。基本上,EnteredMail和enteredPassword代表登录表单上输入的数据。如果身份验证成功,loggedIn布尔值将变为true,并且登录的用户对象存储在checkedUser变量中Jsf 在每次页面刷新时调用会话范围的托管Bean构造函数,jsf,Jsf,我正在使用会话范围的托管bean来处理JavaEE应用程序中的登录。在我对用户进行身份验证之后,用户对象保存在这个会话bean中。但是,在刷新页面之后,会话bean值就消失了 我正在调试代码,结果是在页面刷新时再次调用会话范围的托管bean的构造函数,因此使用新用户初始化用户对象。我想这不是一个正常的行为,因为它应该在会话中保留,不是吗 我正在发布登录管理bean的一些部分,包括参数和登录方法。基本上,EnteredMail和enteredPassword代表登录表单上输入的数据。如果身份验证成
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
@ManagedBean
@SessionScoped
public class LoginController implements Serializable {
@EJB
private LoginSessionBean loginSessionBean;
@EJB
private LecturerFacade lecturerFacade;
private Lecturer checkedUser;
private String enteredEmail;
private String enteredPassword;
private boolean loggedIn;
/** Creates a new instance of loginController */
public LoginController() {
loggedIn = false;
checkedUser = new Lecturer();
}
public String login(){
RequestContext context = RequestContext.getCurrentInstance();
FacesMessage msg = null;
this.setCheckedUser(lecturerFacade.findLecturerByEmail(enteredEmail));
if(loginSessionBean.checkPassword(checkedUser, enteredPassword))
{
loggedIn = true;
msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Welcome", checkedUser.getFirstName()+ " " + checkedUser.getLastName());
FacesContext.getCurrentInstance().addMessage(null, msg);
context.addCallbackParam("loggedIn", loggedIn);
}
return "Index";
我还发布了上述托管bean使用的两个EJB。讲师Facade使用输入的电子邮件检索用户对象,而loginSessionBean检查密码
@Stateless
public class LecturerFacade extends AbstractFacade<Lecturer> {
@PersistenceContext(unitName = "EffectinetWebPU")
private EntityManager em;
Logger logger = Logger.getLogger("MyLog");
FileHandler fh;
protected EntityManager getEntityManager() {
return em;
}
public LecturerFacade() {
super(Lecturer.class);
}
public Lecturer findLecturerByEmail(String email) {
try {
return (Lecturer) this.getEntityManager().createQuery("SELECT l FROM Lecturer l WHERE l.email = :email").setParameter("email", email).getSingleResult();
} catch (NoResultException e) {
System.err.println("Caught NOResultException: "+ e.getMessage());
return null;
} catch (NonUniqueResultException e) {
System.err.println("Caught NonUniqueResultException: "+ e.getMessage());
return null;
} catch (IllegalStateException e) {
System.err.println("Caught IllegalStateException: "+ e.getMessage());
return null;
}
}
}
如果有人对出了什么问题有任何建议,请告诉我
我使用GlassFish3.1作为应用服务器,Primefaces作为JSF库。另外,我已经检查并从正确的包导入了sessionScoped注释,而不是从javax.enterprise…我今天设法解决了它。这就是问题所在,尽管我无法解释原因: 我使用PrimeFaces3.2作为JSF库,所以这是索引页面的主菜单
<h:form>
<p:menubar >
<p:menuitem id="registerLink" value="Register" rendered="#{!loginController.loggedIn}" onclick="registerDialog.show()" />
<p:menuitem id="loginLink" value="Login" rendered="#{!loginController.loggedIn}" onclick="loginDialog.show()" />
<p:submenu label="Units" rendered="true">
<p:menuitem id="addNew" value="Add New" onclick="createUnitDialog.show()" />
<p:menuitem id="myUnits" value="My Units" onclick="" />
</p:submenu>
<p:menuitem id="results" value="Results/Statistics" rendered="#{loginController.loggedIn}" onclick=""/>
<p:menuitem id="profile" value="My Profile" rendered="#{loginController.loggedIn}" onclick=""/>
<p:menuitem id="logout" value="Logout" rendered="#{loginController.loggedIn}" onclick="#{loginController.logout()}"/>
</p:menubar>
</h:form>
在为整个代码设置断点之后,我发现在每次页面刷新时都会调用logout()方法,该方法应该会破坏托管bean。我不知道为什么会发生这种情况,因为它应该在单击注销菜单项时调用
但是,在使用action=“#{loginController.logout()}
更改onclick=“#{loginController.logout()}
后,问题得到了解决
我查看了Primefaces的文档,但没有解释这种行为。今天我设法解决了它。这就是问题所在,尽管我无法解释原因: 我使用PrimeFaces3.2作为JSF库,所以这是索引页面的主菜单
<h:form>
<p:menubar >
<p:menuitem id="registerLink" value="Register" rendered="#{!loginController.loggedIn}" onclick="registerDialog.show()" />
<p:menuitem id="loginLink" value="Login" rendered="#{!loginController.loggedIn}" onclick="loginDialog.show()" />
<p:submenu label="Units" rendered="true">
<p:menuitem id="addNew" value="Add New" onclick="createUnitDialog.show()" />
<p:menuitem id="myUnits" value="My Units" onclick="" />
</p:submenu>
<p:menuitem id="results" value="Results/Statistics" rendered="#{loginController.loggedIn}" onclick=""/>
<p:menuitem id="profile" value="My Profile" rendered="#{loginController.loggedIn}" onclick=""/>
<p:menuitem id="logout" value="Logout" rendered="#{loginController.loggedIn}" onclick="#{loginController.logout()}"/>
</p:menubar>
</h:form>
在为整个代码设置断点之后,我发现在每次页面刷新时都会调用logout()方法,该方法应该会破坏托管bean。我不知道为什么会发生这种情况,因为它应该在单击注销菜单项时调用
但是,在使用action=“#{loginController.logout()}
更改onclick=“#{loginController.logout()}
后,问题得到了解决
我查看了Primefaces的文档,但没有解释这种行为因此,您的问题就在这里:
<p:menuitem value="Logout" ... onclick="#{loginController.logout()}"/>
onclick
属性还接受一个ValueExpression
,因此您甚至可以让JSF/EL相应地自动生成其值:
onclick="#{bean.onclickFunction}"
与
因此,当呈现页面时,将对所有EL进行评估。在您的特定情况下,每次计算EL时都会调用logout()
方法,因此每次呈现页面时都会使会话无效
您需要将它绑定到一个属性,该属性采用方法表达式,如
,
,在这种情况下是
这可以通过理解基本的HTML和JavaScript概念并记住JSF最终生成HTML/CSS/JS来理解。在webbrowser中打开JSF页面,右键单击并查看源代码以实现它。因此,您的问题在这里:
<p:menuitem value="Logout" ... onclick="#{loginController.logout()}"/>
onclick
属性还接受一个ValueExpression
,因此您甚至可以让JSF/EL相应地自动生成其值:
onclick="#{bean.onclickFunction}"
与
因此,当呈现页面时,将对所有EL进行评估。在您的特定情况下,每次计算EL时都会调用logout()
方法,因此每次呈现页面时都会使会话无效
您需要将它绑定到一个属性,该属性采用方法表达式,如
,
,在这种情况下是
这可以通过理解基本的HTML和JavaScript概念并记住JSF最终生成HTML/CSS/JS来理解。在webbrowser中打开JSF页面,右键单击并查看源代码以实现它。您做错了什么。请发布代码和/或配置的相关部分。如何验证用户身份?我刚刚发布了一些代码部分。谢谢你的帮助!可能您的会话在代码中的某个地方被破坏了,例如在LoginSessionBean
?@MattHandy中,我不认为会话可能在EJB中被破坏。无论如何,我在问题中添加了两个EJB。如果可以的话,请看一看谢谢你做错了什么事。请发布代码和/或配置的相关部分。如何验证用户身份?我刚刚发布了一些代码部分。谢谢你的帮助!可能您的会话在代码中的某个地方被破坏了,例如在LoginSessionBean
?@MattHandy中,我不认为会话可能在EJB中被破坏。无论如何,我在问题中添加了两个EJB。如果可以的话请看一看谢谢
<p:menuitem value="Logout" ... action="#{loginController.logout()}"/>