在每个页面刷新时调用Session Scoped Managed Bean构造函数

int*_*boy 0 jsf

我正在使用会话范围的托管bean来处理Java EE应用程序中的登录.在对用户进行身份验证后,用户对象将保存在此会话Bean中.但是,刷新页面后,会话bean值就消失了.

我正在调试代码,结果是在页面刷新时再次调用会话范围的托管bean的构造函数,因此使用新用户初始化用户对象.我想这不是一个正常的行为,因为它应该保存在会话上不应该吗?

我发布了登录托管bean的一些部分,包括参数和登录方法.基本上,enteredEmail和enteredPassword代表登录表单上输入的数据.如果身份验证成功,则loggedIn布尔值将变为true,并且登录的用户对象将存储在checkedUser变量中.

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";
Run Code Online (Sandbox Code Playgroud)

我也发布了上面托管bean使用的两个EJB.讲师使用输入的电子邮件检索用户对象,而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;
    }
}
Run Code Online (Sandbox Code Playgroud)

_

@Stateless

public class LoginSessionBean {

// Add business logic below. (Right-click in editor and choose
// "Insert Code > Add Business Method")
@PersistenceContext(unitName = "EffectinetWebPU")
private EntityManager em;

protected EntityManager getEntityManager() {
    return em;
}

public void setEntityManager(EntityManager em) {
    this.em = em;
}



public boolean checkPassword(Lecturer user, final String enteredPassword) {
    if (user.getPassword().equals(enteredPassword)) {
        return true;
    } else {
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

}

如果有人对出了什么问题有任何建议,请告诉我

我使用glassfish 3.1作为应用程序服务器,使用Primefaces作为JSF库.另外,我已检查并从右侧包中导入sessionScoped注释,而不是从javax.enterprise ...

Bal*_*usC 6

你的问题就在这里:

<p:menuitem value="Logout" ... onclick="#{loginController.logout()}"/>
Run Code Online (Sandbox Code Playgroud)

onclick属性应表示JavaScript处理程序函数,当最终用户单击该元素时,该函数将在Web浏览器中执行.就像是

onclick="alert('You have clicked this element!')"
Run Code Online (Sandbox Code Playgroud)

onclick属性也接受a ValueExpression,因此您甚至可以让JSF/EL自动生成其值:

onclick="#{bean.onclickFunction}"
Run Code Online (Sandbox Code Playgroud)

public String getOnclickFunction() {
    return "alert('You have clicked this element!')";
}
Run Code Online (Sandbox Code Playgroud)

因此,在呈现页面时评估所有EL.在您的特定情况下,logout()每次评估EL时都会调用该方法,因此每次呈现页面时都会使会话无效!

您需要将它绑定到一个MethodExpression类似的属性<h:commandLink action>,<h:commandButton action>在这种特殊情况下<p:menuitem action>.

<p:menuitem value="Logout" ... action="#{loginController.logout()}"/>
Run Code Online (Sandbox Code Playgroud)

这可以通过理解基本的HTML和JavaScript概念来理解,并记住JSF最终生成HTML/CSS/JS.在webbrowser中打开JSF页面,右键单击并查看源代码以实现它.