jsf2要求绕过Validator.validate(),但仍然验证表单

时间:2014-06-06 22:38:55

标签: jsf-2 jsf-2.2

我需要使用“保存您的工作”以及“提交”按钮来实现表单。用户需要能够在完成之前保存他们的工作。这会导致验证问题 所需的价值。我已经看过这里建议的解决方案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(),但仍然会对所需字段验证表单。

任何人都可以看到什么是错误的,否则它似乎是一个优雅的解决方案?

提前致谢。

0 个答案:

没有答案