我需要使用“保存您的工作”以及“提交”按钮来实现表单。用户需要能够在完成之前保存他们的工作。这会导致验证问题 所需的价值。我已经看过这里建议的解决方案JSF 2.0: How to skip JSR-303 bean validation?和其他人喜欢的解决方案。它们需要向需要验证的按钮添加参数
<h:commandButton>
<f:param name="SHOW_VALIDATION" value="true" />
</h:commandButton>
然后用测试装饰每个输入标签
<h:inputText>
<f:validateRequired disabled="#{!param['VALIDATE']}" />
</h:inputText>
概述了更清洁,更安全的解决方案 http://javalabor.blogspot.com/2012/02/jsf-2-conditional-validation.html。这里也尝试了这种方法https://community.jboss.org/thread/211982?tstart=0&_sscc=t。更清洁,因为表单中只需要进行一次更改,以指示哪个按钮应使用按钮的ID跳过验证。更安全,因为没有为可能被操纵的请求添加参数,其目的是绕过验证!目标是替换基本验证器,以便自定义验证器可以检测单击的按钮并跳过整个页面上的验证。
faces-config.xml是
<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.2"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">
<application>
<default-validators>
<validator-id>javax.faces.Bean</validator-id>
</default-validators>
<default-validators>
<validator-id>javax.faces.Required</validator-id>
</default-validators>
</application>
<validator>
<validator-id>javax.faces.Bean</validator-id>
<validator-class>edu.wustl.mir.ctt.util.SkipBeanValidator</validator-class>
</validator>
<validator>
<validator-id>javax.faces.Required</validator-id>
<validator-class>edu.wustl.mir.ctt.util.SkipRequiredValidator</validator-class>
</validator>
自定义验证器
public class SkipRequiredValidator extends RequiredValidator {
@Override
public void validate(final FacesContext context, final UIComponent component, final Object value) {
if (ValidatorUtil.check(context)) {
super.validate(context, component, value);
}
}
}
public class SkipBeanValidator extends BeanValidator {
@Override
public void validate(final FacesContext context, final UIComponent component, final Object value) {
if (ValidatorUtil.check(context)) {
super.validate(context, component, value);
}
}
}
辅助类
public class ValidatorUtil {
private static final String VALIDATE = "VALIDATE";
public static boolean check() {
return check(FacesContext.getCurrentInstance());
}
public static boolean check(final FacesContext context) {
final ExternalContext externalContext = context.getExternalContext();
final Object validate = externalContext.getRequestMap().get(VALIDATE);
if (validate != null) {
return (Boolean) validate;
}
for (final Map.Entry<String, String[]> requestParameters : externalContext.getRequestParameterValuesMap()
.entrySet()) {
final String key = requestParameters.getKey();
if (key.contains(":do")) {
externalContext.getRequestMap().put(VALIDATE, Boolean.TRUE);
return true;
}
}
externalContext.getRequestMap().put(VALIDATE, Boolean.FALSE);
return false;
}
}
使用tomcat7和mojarra2.2,我可以看到自定义的必需验证器确实已被替换,并且不会根据检测到的按钮ID调用super.validate(),但仍然会对所需字段验证表单。
任何人都可以看到什么是错误的,否则它似乎是一个优雅的解决方案?
提前致谢。