2

I'm trying to improve my web app. I read this article http://balusc.blogspot.com/2011/01/jsf-20-tutorial-with-eclipse-and.html and tried to implement some of the ajax stuff (I'm very new to JSF and Ajax).

So the first form works as expected, but when I pass to the second page the message malformedXML: During update: accessForm:passMessage not found is shown in an alert box.

Can anyone explain me why?

    <h:form id="accessForm">
        <h:panelGrid columns="3">
            <h:outputLabel for="user" value="Usuario:"
                           style="float: right" />
            <h:inputText id="user" value="#{userVerifier.username}"
                         required="true"
                         requiredMessage="Introduzca su nombre de usuario.">
                <f:ajax event="blur" render="userMessage" />
            </h:inputText>
            <h:message id="userMessage" for="user" style="color: #FF0000;" />

            <h:outputLabel for="pass" value="Contraseña:" 
                           style="float: right" />
            <h:inputSecret id="pass" value="#{userVerifier.password}"
                           required="true"
                           requiredMessage="Introduzca su contraseña." redisplay="true">
                <f:ajax event="blur" render="passMessage" />
            </h:inputSecret>
            <h:message id="passMessage" for="pass" style="color: #FF0000;" />

            <h:panelGroup />
            <h:commandButton value="  Entrar  " action="#{userVerifier.check}" 
                             style="float: right" >
                <f:ajax execute="@form" render="@form" />
            </h:commandButton>
            <h:messages globalOnly="true" layout="table" />
        </h:panelGrid>
    </h:form>

Thanks in advance.

Update

Here's the Bean code:

@ManagedBean
@SessionScoped
public class UserVerifier{

    private String username;
    private String password;
    private String dependencia;
    private String tipoUsuario;
    private final Database db = new Database();

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getDependencia() {
        return dependencia;
    }

    public void setDependencia(String dependencia) {
        this.dependencia = dependencia;
    }

    public String getTipoUsuario() {
        return tipoUsuario;
    }

    public void setTipoUsuario(String tipoUsuario) {
        this.tipoUsuario = tipoUsuario;
    }

    public String check() {
        String isValidUser = db.checkUser(username, password);
        if (isValidUser.equals("T")) {
            dependencia = db.getDependencia(username, password);
            tipoUsuario = db.getTipoUsuario(username);
            System.out.println("tipoDepe: " + dependencia);
            System.out.println("tipoUser: " + tipoUsuario);
            if (dependencia != null && tipoUsuario != null) {
                return "upload-file";
            } else {
                setUsername("");
                setPassword("");
                return "index";
            }
        } else if (isValidUser.equals("F")) {
            setUsername("");
            setPassword("");
            return "index";
        } else {
            return "error-pnf";
        }
    }
}
BRabbit27
  • 6,333
  • 17
  • 90
  • 161
  • What JSF impl/version? (or are you using Glassfish's default one? if so, which Glassfish version?) Are you using `rendered` attribute anywhere? This error suggests that a component is not been rendered while it has to be updated, but I don't see it back in your code. – BalusC Nov 11 '11 at 19:09
  • Nope, I'm not using `rendered` attribute anywhere. I'm using Mojarra 2.1.4 and Tomcat 7. – BRabbit27 Nov 11 '11 at 19:14
  • In the `action="#{userVerifier.check}"` of the `` in the function of the bean I return a String so I can go to next page. – BRabbit27 Nov 11 '11 at 19:40
  • What browser are you using? I can't reproduce this problem in FF, GC and IE. – BalusC Nov 11 '11 at 19:50
  • I'm using Google Chrome. – BRabbit27 Nov 11 '11 at 19:52
  • Which version? I've here GC 15.0 (on Win7 x64). Have you tried it in other browsers? – BalusC Nov 11 '11 at 19:54
  • Yes. GC 15 Win7 x64. Also tried in IE9 and still the same problem. BUT FF 7.0.1 works fine. So is it Web-Browser-related problem? – BRabbit27 Nov 11 '11 at 19:59
  • 1
    I'm not sure. Anyway, this error indicates a race condition in handling ajax requests. The action occurred before the blur. Try adding `?faces-redirect=true` to the navigation outcome value. Using (default) forward on POST navigation is a poor practice anyway. – BalusC Nov 11 '11 at 20:08
  • Ok. I'll try it and keep that in mind. So what's the best way to pass from one page to another in JSF?... Addint `?faces-redirect=true` that worked, but what does that really mean? and what's POST nav? – BRabbit27 Nov 11 '11 at 20:16

1 Answers1

2

This error indicates a race condition in handling ajax requests. The ajax request of the action method occurred before the ajax request of the blur validation. Try adding ?faces-redirect=true to the navigation outcome value of the action method. JSF should then surely block all open ajax requests in the queue.

public String check() {
    // ...
    return "nextpage?faces-redirect=true";
}

Using (default) forward on POST navigation is a poor practice anyway as the enduser would otherwise end up with an unchanged URL in browser address bar and a non-bookmarkable page. See also When should I use h:outputLink instead of h:commandLink?

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555