How to display my application's errors in JSF?

左心房为你撑大大i 提交于 2019-11-27 02:50:56

FacesContext.addMessage(String, FacesMessage) requires the component's clientId, not it's id. If you're wondering why, think about having a control as a child of a dataTable, stamping out different values with the same control for each row - it would be possible to have a different message printed for each row. The id is always the same; the clientId is unique per row.

So "myform:mybutton" is the correct value, but hard-coding this is ill-advised. A lookup would create less coupling between the view and the business logic and would be an approach that works in more restrictive environments like portlets.

<f:view>
  <h:form>
    <h:commandButton id="mybutton" value="click"
      binding="#{showMessageAction.mybutton}"
      action="#{showMessageAction.validatePassword}" />
    <h:message for="mybutton" />
  </h:form>
</f:view>

Managed bean logic:

/** Must be request scope for binding */
public class ShowMessageAction {

    private UIComponent mybutton;

    private boolean isOK = false;

    public String validatePassword() {
        if (isOK) {
            return "ok";
        }
        else {
            // invalid
            FacesMessage message = new FacesMessage("Invalid password length");
            FacesContext context = FacesContext.getCurrentInstance();
            context.addMessage(mybutton.getClientId(context), message);
        }
        return null;
    }

    public void setMybutton(UIComponent mybutton) {
        this.mybutton = mybutton;
    }

    public UIComponent getMybutton() {
        return mybutton;
    }
}

In case anyone was curious, I was able to figure this out based on all of your responses combined!

This is in the Facelet:

<h:form id="myform">
  <h:inputSecret value="#{createNewPassword.newPassword1}" id="newPassword1" />
  <h:message class="error" for="newPassword1" id="newPassword1Error" />
  <h:inputSecret value="#{createNewPassword.newPassword2}" id="newPassword2" />
  <h:message class="error" for="newPassword2" id="newPassword2Error" />
  <h:commandButton value="Continue" action="#{createNewPassword.continueButton}" />
</h:form>

This is in the continueButton() method:

FacesContext.getCurrentInstance().addMessage("myForm:newPassword1", new FacesMessage(PASSWORDS_DONT_MATCH, PASSWORDS_DONT_MATCH));

And it works! Thanks for the help!

You also have to include the FormID in your call to addMessage().

 FacesContext.getCurrentInstance().addMessage("myform:newPassword1", new FacesMessage("Error: Your password is NOT strong enough."));

This should do the trick.

Regards.

InfZero

Remember that:

FacesContext context = FacesContext.getCurrentInstance();
context.addMessage( null, new FacesMessage( "The message to display in client" ));            

is also valid, because when null is specified as first parameter, it is applied to the whole form.

More info: coreservlets.com //Outdated

JSF is a beast. I may be missing something, but I used to solve similar problems by saving the desired message to a property of the bean, and then displaying the property via an outputText:

<h:outputText
    value="#{CreateNewPasswordBean.errorMessage}"
    render="#{CreateNewPasswordBean.errorMessage != null}" />

Found this while Googling. The second post makes a point about the different phases of JSF, which might be causing your error message to become lost. Also, try null in place of "newPassword" because you do not have any object with the id newPassword.

I tried this as a best guess, but no luck:

It looks right to me. Have you tried setting a message severity explicitly? Also I believe the ID needs to be the same as that of a component (i.e., you'd need to use newPassword1 or newPassword2, if those are your IDs, and not newPassword as you had in the example).

FacesContext.getCurrentInstance().addMessage("newPassword1", 
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error Message"));

Then use <h:message for="newPassword1" /> to display the error message on the JSF page.

Simple answer, if you don't need to bind it to a specific component...

Java:

            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Authentication failed", null);
            FacesContext context = FacesContext.getCurrentInstance();
            context.addMessage(null, message);      

XHTML:

            <h:messages></h:messages>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!