42

在我的 JSF/Facelets 应用程序中,这是我的部分表单的简化版本:

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

我希望能够根据 continueButton() 方法中发生的事情将错误分配给特定的 h:message 标记。newPassword 和 newPassword2 需要显示不同的错误。验证器不会真正起作用,因为将传递结果(来自数据库)的方法在 continueButton() 方法中运行,并且运行两次的成本太高。

我不能使用 h:messages 标记,因为该页面有多个地方需要显示不同的错误消息。当我尝试这样做时,页面显示每条消息的重复项。

我试过这个作为最好的猜测,但没有运气:

public Navigation continueButton() {
  ...
  expensiveMethod();
  if(...) {
    FacesContext.getCurrentInstance().addMessage("newPassword", new FacesMessage("Error: Your password is NOT strong enough."));
  }
}

我错过了什么?任何帮助,将不胜感激!

4

8 回答 8

58

FacesContext.addMessage(String, FacesMessage)需要组件的clientId 不是id。如果您想知道为什么,请考虑将控件作为 dataTable 的子项,为每一行使用相同的控件标记不同的值 - 可以为每一行打印不同的消息。id总是一样的;clientId每行都是唯一的。

所以“myform:mybutton”是正确的值,但是硬编码是不明智的。查找将在视图和业务逻辑之间创建较少的耦合,并且将是一种适用于更严格的环境(如 portlet)的方法。

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

托管bean逻辑:

/** 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;
    }
}
于 2008-11-26T18:44:41.093 回答
25

万一有人好奇,我可以根据您的所有回答结合起来弄清楚这一点!

这是在 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>

这是在 continueButton() 方法中:

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

它有效!谢谢您的帮助!

于 2008-11-25T21:57:26.273 回答
6

您还必须在调用 addMessage() 时包含 FormID。

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

这应该可以解决问题。

问候。

于 2008-11-25T14:44:29.720 回答
4

请记住:

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

也是有效的,因为当将null指定为第一个参数时,它将应用于整个表单。

更多信息:coreservlets.com //过时

于 2012-07-10T23:25:47.817 回答
2

JSF 是一头野兽。我可能遗漏了一些东西,但我曾经通过将所需的消息保存到 bean 的属性,然后通过 outputText 显示属性来解决类似的问题:

<h:outputText
    value="#{CreateNewPasswordBean.errorMessage}"
    render="#{CreateNewPasswordBean.errorMessage != null}" />
于 2008-11-24T23:23:53.683 回答
1

谷歌搜索时发现了这个。第二篇文章指出了 JSF 的不同阶段,这可能会导致您的错误消息丢失。此外,请尝试使用 null 代替“newPassword”,因为您没有任何 ID 为 newPassword 的对象。

于 2008-11-24T23:10:48.890 回答
1

我试过这个作为最好的猜测,但没有运气:

在我看来是对的。您是否尝试过明确设置消息严重性?此外,我认为 ID 需要与组件的 ID 相同(即,如果这些是您的 ID,则需要使用 newPassword1 或 newPassword2,而不是示例中的 newPassword)。

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

然后用于<h:message for="newPassword1" />在 JSF 页面上显示错误消息。

于 2008-11-25T10:07:40.420 回答
0

简单的答案,如果您不需要将其绑定到特定组件...

爪哇:

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

XHTML:

            <h:messages></h:messages>
于 2018-05-21T16:53:04.603 回答