【问题标题】:Mark inputText as invalid in Invoke Applications phase在调用应用程序阶段将 inputText 标记为无效
【发布时间】:2014-10-21 04:25:57
【问题描述】:

我在 Invoke Applications 阶段执行一些业务规则验证,当出现错误时,会抛出自定义异常。自定义异常在自定义 JSF ErrorHandler 中处理,其中有问题的输入组件将被标记为无效,FacesMessages 被创建并且 FacesContext 上的验证将失败。

豆子

public void performAction() {

    if ("aaa".equals(input)) {
        // custom exception: arg1 - Error Message, arg2 - clientId
        throw new ServiceValidationException("Something went wrong", ":f:input");
    }
}

XHTML

<h:form id="f">
    <p:inputText id="input" value="#{bean.input}" />
    <h:commandButton value="Submit" action="#{bean.performAction}"/>
</h:form>

自定义 JSF ErrorHandler

@Override
public void handle() throws FacesException {

    try {
        Iterator<ExceptionQueuedEvent> unhandledExceptionQueuedEvents = getUnhandledExceptionQueuedEvents().iterator();
        if (unhandledExceptionQueuedEvents.hasNext()) {
            Throwable exception = unhandledExceptionQueuedEvents.next().getContext().getException();
            Throwable rootCause = unwrapRootCause(exception);

            if (rootCause instanceof ServiceValidationException) {

                ServiceValidationException sve = (ServiceValidationException) rootCause;
                JSFComponentUtil.markComponentAsInvalid(sve.getClientId());
                // create FacesMessage here etc
                ...
                FacesContext.getCurrentInstance().validationFailed();
                return;
            }
        }
    } catch (Exception e) {
        logger.error("Error encountered while processing exception, allow default error handling to take over", e);
    }
    // delegate to Omnifaces Ajax exception handler
    super.handle();
}

JSFComponentUtil

public static void markComponentAsInvalid(String componentId) {
    UIComponent component = findComponent(componentId);
    if (component != null && component instanceof EditableValueHolder) {
        EditableValueHolder evh = (EditableValueHolder) component;
        if (evh.isValid()) {
            evh.setValid(false);
        }
    } else {
        LOG.debug("component not found or is not instance of EditableValueHolder");
    }
}

public static UIComponent findComponent(String componentId) {
    UIViewRoot viewRoot = FacesContext.getCurrentInstance().getViewRoot();
    if (viewRoot != null) {
        return viewRoot.findComponent(componentId);
    }
    LOG.debug("View Root is null, returning null");
    return null;
}

问题 我遇到的问题是,通过命令按钮提交表单后,页面重新显示,输入文本字段标记为红色(预期行为),但是输入该字段的文本丢失了。我希望输入的无效文本保留在该字段中。

【问题讨论】:

  • “JSF 方式”是使用普通验证器执行验证。

标签: validation jsf-2 primefaces error-handling


【解决方案1】:

在markComponentInvalid中,可以尝试手动设置组件的值:

evh.setSubmittedValue("aaa");
evh.setValue("aaa");

当然,您可以向 ServiceValidationClass 添加一个“input”属性,而不是硬编码“aaa”,这样您就可以将该值从操作方法传递给错误处理程序,然后传递给 Util 类,例如

豆子:

throw new ServiceValidationClass ("Something went wrong", ":f:input", input);

错误处理程序:

JSFComponentUtil.markComponentAsInvalid(sve.getClientId(), sve.getInput());

等等

【讨论】:

  • 这是一个想法。如果没有其他“JSF 方式”来处理这个问题,我会接受这个答案。谢谢!
猜你喜欢
  • 2011-10-25
  • 1970-01-01
  • 1970-01-01
  • 2018-02-22
  • 1970-01-01
  • 2011-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多