Diego Borda Diego Borda - 4 years ago 212
Java Question

javax.faces.ViewState lost on p:commandButton action

I have a simple login form that calls an action which if login is successful returns the view id of the secured area. I would like to use ajax for the action but when the page gets redirected javax.faces.ViewState is not present in the form making the user have to click twice in order to restore it. If I set ajax="false" everything works fine except that I loose my cool transition achieved with p:ajaxSatatus.

I have dealt with this kind of issue before using this blog entry by BlausC http://balusc.blogspot.com/2011/09/communication-in-jsf-20.html#AjaxRenderingOfContentWhichContainsAnotherForm
I have also seen h:commandLink / h:commandButton is not being invoked

I successfully worked around the issue in the past with richfaces but now I'm stuck.

My enviroment is:
Mojarra 2.1.6
PrimeFaces 3.4.2
GlassFish Server Open Source Edition 3.1.2.2

Code:

<h:form id="loginForm">
<div style="margin: 0px auto; width: 300px;">
<p:messages />
<p:panelGrid columns="2" styleClass="panelGridNoBorder">
<h:outputLabel value="Name: " for="txtPrincipal"/>
<p:inputText id="txtPrincipal" value="#{userBean.principal}"/>
<h:outputLabel value="Email:" for="txtPassword"/>
<p:password id="txtPassword" value="#{userBean.password}" />
</p:panelGrid>
<p:commandButton id="loginButon" action="#{userBean.login}" value="Login"/>
</div>
</h:form>


UserBean.java @SessionScoped

public String login() {
try {
HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
loginedUser = autenticator.authenticate(principal, passHash, request.getRemoteAddr());
request.login(principal, passHash);
if (loginedUser != null) {
return "/admin/index.xhtml";
} else {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Usuario o contraseña incorrecto", "Usuario o contraseña incorrecto");
FacesContext.getCurrentInstance().addMessage(null, message);
return null;
}
} catch (ServletException ex) {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Usuario o contraseña incorrecto", "Usuario o contraseña incorrecto");
FacesContext.getCurrentInstance().addMessage(null, message);
return null;
}
}


Thanks for the help

Answer Source

Your concrete problem is recognizable if you're using MSIE browser. You basically need to override the PrimeFaces ajax response handler. See also this answer for a concrete code example.

But, much better is to just send a redirect after login. That's also the canonical approach conform the Post-Redirect-Get pattern.

return "/admin/index.xhtml?faces-redirect=true";
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download