我正在调用应用程序阶段执行一些业务规则验证,当出现错误时,将抛出自定义异常。自定义异常在自定义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;
}
问题 我遇到的问题是,在通过命令按钮提交表单后,页面将重新显示,输入文本字段标记为红色(预期行为),但输入字段的文本将丢失。我希望输入的无效文本保留在字段中。
答案 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());
等