如何在JSF中显示我的应用程序错误?

Eri*_*oob 40 error-handling jsf facelets

在我的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>
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

McD*_*ell 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>
Run Code Online (Sandbox Code Playgroud)

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


Eri*_*oob 24

如果有人好奇,我能够根据你所有的反应结合出来做出来!

这是在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>
Run Code Online (Sandbox Code Playgroud)

这是在continueButton()方法中:

FacesContext.getCurrentInstance().addMessage("myForm:newPassword1", new FacesMessage(PASSWORDS_DONT_MATCH, PASSWORDS_DONT_MATCH));
Run Code Online (Sandbox Code Playgroud)

它的工作原理!谢谢您的帮助!


huo*_*o73 6

您还必须在对addMessage()的调用中包含FormID.

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

这应该可以解决问题.

问候.