素验证的bean验证(JSR 303)不起作用 [英] bean validation (JSR 303) for primefaces not working

查看:82
本文介绍了素验证的bean验证(JSR 303)不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用:

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

我遵循以下示例中使用后端bean进行CSV(客户端验证)的示例:

我现在得到的是:

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标签验证

是我错过了配置的任何事情,还是jar的差异版本导致了该问题?

解决方案

通过放置依赖项(即slf4j-jdk14,slf4j-api和jboss-el),Hibernate Validator可以在Tomcat 9上运行,但不能在GAE上运行.将日志级别配置为FINER后,记录器将显示以下内容:

  2017年5月4日上午9:10:08 com.sun.faces.config.processor.ApplicationConfigProcessor addSystemEventListener精细:使用侦听器org.primefaces.extensions.application.PostConstructApplicationEventListener订阅事件javax.faces.event.PostConstructApplicationEvent和源javax.faces.application.Application2017年5月4日上午9:10:08 com.sun.faces.config.processor.ApplicationConfigProcessor isBeanValidatorAvailable精细:java.lang.NoClassDefFoundError:javax.naming.InitialContext是一个受限类.有关更多详细信息,请参阅Google App Engine开发人员指南.java.lang.NoClassDefFoundError:javax.naming.InitialContext是一个受限类.有关更多详细信息,请参阅Google App Engine开发人员指南.在com.google.appengine.tools.development.agent.runtime.Runtime.reject(Runtime.java:50)在com.sun.faces.config.processor.ApplicationConfigProcessor.isBeanValidatorAvailable(ApplicationConfigProcessor.java:434)在com.sun.faces.config.processor.ApplicationConfigProcessor.registerDefaultValidatorIds(ApplicationConfigProcessor.java:396)在com.sun.faces.config.processor.ApplicationConfigProcessor.process(ApplicationConfigProcessor.java:353)在com.sun.faces.config.processor.AbstractConfigProcessor.invokeNext(AbstractConfigProcessor.java:152)在com.sun.faces.config.processor.LifecycleConfigProcessor.process(LifecycleConfigProcessor.java:137) 

这是一个"NoClassDefFoundError",但是登录到FINE级别而不是Warning并返回更有意义的消息.那么不好.

因此,我对isBeanValidatorAvailable()进行了如下更改,以使其可以在GAE上运行

 静态布尔值isBeanValidatorAvailable(){布尔结果=假;最后的String beansValidationAvailabilityCacheKey ="javax.faces.BEANS_VALIDATION_AVAILABLE";Map< String,Object>appMap = FacesContext.getCurrentInstance().getExternalContext().getApplicationMap();如果(appMap.containsKey(beansValidationAvailabilityCacheKey)){结果=(布尔值)appMap.get(beansValidationAvailabilityCacheKey);} 别的 {尝试 {//Google App Engine的代码ValidatorFactoryvalidatorFactory = null;尝试{对象cachedObject = FacesContext.getCurrentInstance().getExternalContext().getApplicationMap().get(BeanValidator.VALIDATOR_FACTORY_KEY);如果(ValidatorFactory的cachedObject实例){validateatorFactory =(ValidatorFactory)cachedObject;} 别的 {validatorFactory = Validation.buildDefaultValidatorFactory();}} catch(ValidationException e){LOGGER.log(Level.WARNING,无法建立默认的Bean Validator工厂",e);}if(null!= validatorFactory){appMap.put(BeanValidator.VALIDATOR_FACTORY_KEY,validatorFactory);结果=真;}LOGGER.log(Level.FINE,"result =" + result +,ValidatorFactory =" + validatorFactory);/*与Google App Engine不兼容*Thread.currentThread().getContextClassLoader().loadClass("javax.validation.MessageInterpolator");//检查实现是否可用.对象cachedObject = appMap.get(BeanValidator.VALIDATOR_FACTORY_KEY);if(ValidatorFactory的cachedObject实例){结果=真;} 别的 {上下文initialContext = null;尝试 {initialContext =新的InitialContext();} catch(NoClassDefFoundError nde){//禁止在Google App Engine上使用InitialContext,并且GAE抛出NoClassDefFoundError如果(LOGGER.isLoggable(Level.FINE)){LOGGER.log(Level.FINE,nde.toString(),nde);}} catch(NamingException ne){如果(LOGGER.isLoggable(Level.WARNING)){LOGGER.log(Level.WARNING,ne.toString(),ne);}}尝试 {对象validatorFactory = initialContext.lookup("java:comp/ValidatorFactory");if(null!= validatorFactory){appMap.put(BeanValidator.VALIDATOR_FACTORY_KEY,validatorFactory);结果=真;}} catch(NamingException根){如果(LOGGER.isLoggable(Level.FINE)){String msg =无法建立默认的Bean Validator工厂:"+ root.getMessage();LOGGER.fine(msg);}}如果(!结果){尝试 {ValidatorFactory factory = Validation.buildDefaultValidatorFactory();验证程序验证程序= factory.getValidator();appMap.put(BeanValidator.VALIDATOR_FACTORY_KEY,工厂);结果=真;} catch(Throwable throwable){}}}*/} catch(Throwable t){//CNFE或ValidationException或任何其他如果(LOGGER.isLoggable(Level.FINE)){LOGGER.fine(无法加载Beans验证");}}appMap.put(beansValidationAvailabilityCacheKey,结果);}返回结果;} 

毕竟,所有此JSR 303(Bean验证)问题都与对JSF2的GAE限制有关.

可以从 Google云端硬盘中获取工作副本.

>

I'm using:

  • 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

I follow the example for CSV (Client Side Validation) using backend bean from: https://www.primefaces.org/showcase/ui/csv/bean.xhtml

The expected result should be:

And what I get right now:

The bean validation is not working.

I have below configure in web.xml

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

Few similar posts said need downgrade jsf to 2.2.2, I tried but still not working.

Right now the workaround for CSV is either

  • using jsf tag validation based on the demo

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

For example:

<p:inputText id="age" value="#{beanValidationView.age}" label="Age">
    <f:validateLongRange for="age" minimum="10" maximum="20" />
</p:inputText>

  • Or create my own validator

for example: http://www.supermanhamuerto.com/doku.php?id=java:validatorinprimefaces

BTW, I don't think it is related to GAE. Because I tried with a new Dynamic Web Project using Tomcat 9, it give me the same result as shown in below screen capture.

Is that any thing(s) I miss configured or having diff version of jar causing that problem?

解决方案

By placing dependencies (i.e slf4j-jdk14, slf4j-api and jboss-el), Hibernate Validator work on Tomcat 9 but not GAE. After configured the log level to FINER , logger show below 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)

That is a "NoClassDefFoundError", however log in FINE level instead of Warning and return more meaningful message. That bad.

So I make a small change to the isBeanValidatorAvailable() as below to make it work on 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;
}

After all this JSR 303 (Bean Validation) problem is related to GAE restriction on JSF2.

A working copy can get from Google Drive.

这篇关于素验证的bean验证(JSR 303)不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆