在Invoke Applications阶段将inputText标记为无效

时间:2014-08-27 14:18:23

标签: validation jsf-2 primefaces error-handling

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

Bean

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;
}

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

1 个答案:

答案 0 :(得分:0)

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

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

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

豆:

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

错误处理程序:

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