【问题标题】:How to skip action when validation with a custom validator fails?使用自定义验证器验证失败时如何跳过操作?
【发布时间】:2011-05-26 14:30:12
【问题描述】:

我有一个用于图书馆的小型 Web 应用程序,带有一个定制的 ISBN 验证器。我用于添加书籍的 .xhtml 页面如下所示:

<fieldset>
<h:messages/>
<ul>
    <li>
        <h:outputLabel for="isbn" value="#{labels.isbn}:" />
        <h:inputText id="isbn" value="#{addController.book.isbn.isbnValue}" required="true" requiredMessage="- ISBN must be filled in.">
            <f:validator validatorId="isbnValidator" />
        </h:inputText>
    </li>
    <li>
        <h:outputLabel for="title" value="#{labels.title}:" />
        <h:inputText id="title" value="#{addController.book.title}" required="true" requiredMessage="- Title must be filled in."/>
    </li>
    <li>
        <h:outputLabel for="name" value="#{labels.name}:" />
        <h:inputText id="name" value="#{addController.book.person.name}" required="true" requiredMessage="- Name must be filled in."/>
    </li>
    <li>
        <h:outputLabel for="firstname" value="#{labels.firstname}:" />
        <h:inputText id="firstname" value="#{addController.book.person.firstname}" />
    </li>

</ul>
<h:commandButton id="addButton" action="#{addController.save}" value="#{labels.add}" />
<h:commandButton id="cancelButton" action="bookOverview" value="#{labels.cancel}" />
</fieldset>
</ui:define>

第一个输入字段的isbnValidator就是这个类:

private Isbn isbn;

@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
    isbn = new Isbn((String) value);
    if (!isbn.isIsbn17Characters()) {
        addMessageToContext(context, "- ISBN needs to have 17 characters");
    }
    if (isbn.isIsbn17Characters() && !isbn.isIsbnInRightFormat()) {
        addMessageToContext(context, "- Wrong format, it should be like 'XXX-XX-XXX-XXXX-X'");
    }
    if (isbn.isIsbn17Characters() && isbn.isIsbnInRightFormat() && !isbn.isIsbnFormatValid()) {
        addMessageToContext(context, "- ISBN can only contain numbers, and no other tokens");
    }
    if (isbn.isIsbn17Characters() && isbn.isIsbnInRightFormat() && isbn.isIsbnFormatValid()
            && !isbn.isLastNumberValid()) {
        addMessageToContext(context, "- Last number of the ISBN should be " + isbn.getCorrectLastNumber()
                + " with those 12 numbers");
    }

}

public static void addMessageToContext(FacesContext context, String message) {
    FacesMessage facesMessage = new FacesMessage();
    facesMessage.setSummary(message);
    facesMessage.setDetail(message);
    context.addMessage("isbn", facesMessage);
}

当我点击“添加”按钮时,这本书应该被添加到数据库中。

当 ISBN 字段、名称字段或标题字段未填写时,我会收到相应的错误消息。但是当我的字段被填写,并且 ISBN 验证失败时,他显示了错误消息,但他仍然将图书(使用错误的 ISBN 号)添加到数据库中。

我想到的一个解决方案:如果我的messages标签不为空,他不应该将这本书添加到数据库中。但是我该如何检查呢?

或者我的问题有更好的解决方案吗?

【问题讨论】:

    标签: validation jsf


    【解决方案1】:

    验证错误消息处理错误。您需要抛出ValidatorExceptionFacesMessage,而不是手动添加FacesMessage

    所以不是所有这些

    addMessageToContext(context, "- ISBN needs to have 17 characters");
    

    你需要做的

    throw new ValidatorException(new FacesMessage("- ISBN needs to have 17 characters"));
    

    这是 JSF 标志,表示输入无效,因此不会调用操作方法。您也不需要指定客户端 ID,它只会在与触发此验证器的输入组件关联的 &lt;h:message&gt; 中结束。

    【讨论】:

    • 它现在可以工作了,但是如果抛出异常之一,我将无法导航到任何其他页面。我该如何解决?
    猜你喜欢
    • 1970-01-01
    • 2015-10-30
    • 2018-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-10
    相关资源
    最近更新 更多