bean验证(JSR 303)for primefaces不起作用

时间:2017-05-02 14:24:50

标签: validation jsf primefaces bean-validation

我正在使用:

  • Primefaces 6.1
  • JSF:2.2.10
  • javax.validation:1.1.0.Final
  • validator impl:hibernate-validator 5.0.1.Final
  • GAE:1.9.52

我使用后端bean来执行CSV(客户端验证)示例: https://www.primefaces.org/showcase/ui/csv/bean.xhtml

预期结果应为: enter image description here

我现在得到的是:

enter image description here

bean验证无效。

我在web.xml中进行了以下配置

<context-param> 
    <param-name>primefaces.CLIENT_SIDE_VALIDATION</param-name> 
    <param-value>true</param-value> 
</context-param>

很少有类似的帖子说需要将jsf降级到2.2.2,我试过但仍然没有工作。

目前,CSV的解决方法是

  • 使用基于演示的jsf标签验证

https://www.primefaces.org/showcase/ui/csv/basic.xhtml

例如:

<p:inputText id="age" value="#{beanValidationView.age}" label="Age">
    <f:validateLongRange for="age" minimum="10" maximum="20" />
</p:inputText>
  • 或创建我自己的验证器

例如: http://www.supermanhamuerto.com/doku.php?id=java:validatorinprimefaces

顺便说一句,我不认为这与GAE有关。因为我尝试使用Tomcat 9的新动态Web项目,它给出了与下面屏幕截图所示相同的结果。

enter image description here

是否有任何我错过配置的东西或者有不同版本的jar导致了这个问题?

2 个答案:

答案 0 :(得分:1)

我得到了同样的错误。 我通过升级hibernate-validator修复了它: 5.1.3.Final 至: 5.3.5.Final

我保留了Primefaces 6.1。

答案 1 :(得分:0)

通过放置依赖关系(即slf4j-jdk14,slf4j-api和jboss-el),Hibernate Validator可以在Tomcat 9上运行,但不能运行GAE。将日志级别配置为FINER后,logger显示在下面的entriies:

May 04, 2017 9:10:08 AM com.sun.faces.config.processor.ApplicationConfigProcessor addSystemEventListener
FINE: Subscribing for event javax.faces.event.PostConstructApplicationEvent and source javax.faces.application.Application using listener org.primefaces.extensions.application.PostConstructApplicationEventListener
May 04, 2017 9:10:08 AM com.sun.faces.config.processor.ApplicationConfigProcessor isBeanValidatorAvailable
FINE: java.lang.NoClassDefFoundError: javax.naming.InitialContext is a restricted class. Please see the Google  App Engine developer's guide for more details.
java.lang.NoClassDefFoundError: javax.naming.InitialContext is a restricted class. Please see the Google  App Engine developer's guide for more details.
    at com.google.appengine.tools.development.agent.runtime.Runtime.reject(Runtime.java:50)
    at com.sun.faces.config.processor.ApplicationConfigProcessor.isBeanValidatorAvailable(ApplicationConfigProcessor.java:434)
    at com.sun.faces.config.processor.ApplicationConfigProcessor.registerDefaultValidatorIds(ApplicationConfigProcessor.java:396)
    at com.sun.faces.config.processor.ApplicationConfigProcessor.process(ApplicationConfigProcessor.java:353)
    at com.sun.faces.config.processor.AbstractConfigProcessor.invokeNext(AbstractConfigProcessor.java:152)
    at com.sun.faces.config.processor.LifecycleConfigProcessor.process(LifecycleConfigProcessor.java:137)

这是一个&#34; NoClassDefFoundError&#34;但是登录FINE级别而不是Warning并返回更有意义的消息。那么不好。

所以我对isBeanValidatorAvailable()做了一个小改动,如下所示,使其适用于GAE

static boolean isBeanValidatorAvailable() {

    boolean result = false;
    final String beansValidationAvailabilityCacheKey = 
            "javax.faces.BEANS_VALIDATION_AVAILABLE";
    Map<String,Object> appMap = FacesContext.getCurrentInstance().getExternalContext().getApplicationMap();

    if (appMap.containsKey(beansValidationAvailabilityCacheKey)) {
        result = (Boolean) appMap.get(beansValidationAvailabilityCacheKey);
    } else {
        try {       
            // Code for Google App Engine 
            ValidatorFactory validatorFactory = null;
            try{                
                Object cachedObject=FacesContext.getCurrentInstance().getExternalContext().getApplicationMap().get(BeanValidator.VALIDATOR_FACTORY_KEY);
                if (cachedObject instanceof ValidatorFactory) {
                    validatorFactory=(ValidatorFactory)cachedObject;
                } else {
                    validatorFactory=Validation.buildDefaultValidatorFactory();
                }       
            }catch(ValidationException e) {
                LOGGER.log(Level.WARNING, "Could not build a default Bean Validator factory",e);
            }               

            if (null != validatorFactory) {
                appMap.put(BeanValidator.VALIDATOR_FACTORY_KEY, validatorFactory);
                result = true;
            }             
            LOGGER.log(Level.FINE, "result=" +result +", validatorFactory=" +validatorFactory);

         /* incompatible with Google App Engine
          *
            Thread.currentThread().getContextClassLoader().loadClass("javax.validation.MessageInterpolator");
            // Check if the Implementation is available.
            Object cachedObject = appMap.get(BeanValidator.VALIDATOR_FACTORY_KEY);
            if(cachedObject instanceof ValidatorFactory) {
                result = true;
            } else {
                Context initialContext = null;
                try {
                    initialContext = new InitialContext();
                } catch (NoClassDefFoundError nde) {
                    // on google app engine InitialContext is forbidden to use and GAE throws NoClassDefFoundError 
                    if (LOGGER.isLoggable(Level.FINE)) {
                        LOGGER.log(Level.FINE, nde.toString(), nde);
                    }
                } catch (NamingException ne) {
                    if (LOGGER.isLoggable(Level.WARNING)) {
                        LOGGER.log(Level.WARNING, ne.toString(), ne);
                    }
                }

                try {
                    Object validatorFactory = initialContext.lookup("java:comp/ValidatorFactory");
                    if (null != validatorFactory) {
                        appMap.put(BeanValidator.VALIDATOR_FACTORY_KEY, validatorFactory);
                        result = true;
                    }
                } catch (NamingException root) {
                    if (LOGGER.isLoggable(Level.FINE)) {
                        String msg = "Could not build a default Bean Validator factory: " 
                                + root.getMessage();
                        LOGGER.fine(msg);                       
                    }
                }

                if (!result) {
                    try {
                        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
                        Validator validator = factory.getValidator();
                        appMap.put(BeanValidator.VALIDATOR_FACTORY_KEY, factory);
                        result = true;
                    } catch(Throwable throwable) {
                    }
                }
            }
          */
        } catch (Throwable t) { // CNFE or ValidationException or any other
            if (LOGGER.isLoggable(Level.FINE)) {
                LOGGER.fine("Unable to load Beans Validation");
            }
        }
        appMap.put(beansValidationAvailabilityCacheKey, result);
    }
    return result;
}

毕竟这个JSR 303(Bean Validation)问题与JSF2的GAE限制有关。

工作副本可以来自Google Drive