我正在尝试使用Hibernate Validator 5.0.1和JSF2.2,但是自从mojarra 2.2.3版本开始,它们的集成似乎已经被破坏了。我已经创建了一个小应用程序来演示问题并获得异常“javax.servlet.ServletException:Expression Error:Named Object:javax.faces.Bean not found。”在Tomcat 7.0.42上运行时。
有其他人有这个问题吗?
web应用程序/网页/的index.xhtml:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:body>
<h:form>
<h:messages/>
<h:inputText value="#{theBean.z}">
<f:validateBean/>
</h:inputText>
<h:commandButton value="send z"/>
</h:form>
</h:body>
</html>
TheBean.java
package lo.test;
import javax.faces.bean.ManagedBean;
import javax.validation.constraints.Min;
@ManagedBean
public class TheBean {
@Min(5)
private Integer z;
public Integer getZ() {
return z;
}
public void setZ(Integer z) {
this.z = z;
}
}
的web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>pages/index.xhtml</welcome-file>
</welcome-file-list>
</web-app>
依赖关系:
"org.hibernate:hibernate-validator:5.0.1.Final"
"com.sun.faces:jsf-impl:2.2.4"
"com.sun.faces:jsf-api:2.2.4"
异常的完整堆栈跟踪:
javax.faces.FacesException: Expression Error: Named Object: javax.faces.Bean not found.
at com.sun.faces.application.ApplicationImpl.createValidator(ApplicationImpl.java:1596)
at com.sun.faces.facelets.tag.jsf.ValidatorTagHandlerDelegateImpl.createValidator(ValidatorTagHandlerDelegateImpl.java:245)
at com.sun.faces.facelets.tag.jsf.ValidatorTagHandlerDelegateImpl.applyAttachedObject(ValidatorTagHandlerDelegateImpl.java:133)
at com.sun.faces.facelets.tag.jsf.ValidatorTagHandlerDelegateImpl.applyNested(ValidatorTagHandlerDelegateImpl.java:212)
at com.sun.faces.facelets.tag.jsf.ValidatorTagHandlerDelegateImpl.apply(ValidatorTagHandlerDelegateImpl.java:88)
at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137)
at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:190)
at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137)
at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:190)
at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137)
at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:190)
at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
at com.sun.faces.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:93)
at com.sun.faces.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:87)
at com.sun.faces.facelets.impl.DefaultFacelet.apply(DefaultFacelet.java:161)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.buildView(FaceletViewHandlingStrategy.java:980)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:99)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:647)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)
答案 0 :(得分:3)
我能够以这种方式修复它:
public static final String BEANS_VALIDATION_AVAILABILITY_CACHE_KEY = "javax.faces.BEANS_VALIDATION_AVAILABLE";
@PostConstruct
private void init() {
FacesContext.getCurrentInstance().getExternalContext().getApplicationMap().remove(BEANS_VALIDATION_AVAILABILITY_CACHE_KEY);
FacesContext.getCurrentInstance().getExternalContext().getApplicationMap()
.put(BeanValidator.VALIDATOR_FACTORY_KEY, Validation.buildDefaultValidatorFactory());
}
答案 1 :(得分:3)
Mojarra尝试通过JNDI加载bean验证时,似乎在像Tomcat或Jetty这样的servlet容器上出现Mojarra 2.2.3到2.2.6的问题。
我在JavaLand 2014上与Ed Burns讨论了这个问题,这个问题应该用Mojarra 2.2.7解决(见JAVASERVERFACES-3183)。
答案 2 :(得分:2)
这适用于Mojara 2.2.2,但不适用于较新版本。感谢Michail提示。这是预配置Faces的另一种方法:
public class FacesContextBootstrap implements ServletContextListener
{
public static final String BEANS_VALIDATION_AVAILABILITY_CACHE_KEY = "javax.faces.BEANS_VALIDATION_AVAILABLE";
@Override
public void contextInitialized(ServletContextEvent sce) {
FacesContext.getCurrentInstance().getExternalContext().getApplicationMap().remove(BEANS_VALIDATION_AVAILABILITY_CACHE_KEY);
FacesContext.getCurrentInstance().getExternalContext().getApplicationMap()
.put(BeanValidator.VALIDATOR_FACTORY_KEY, Validation.buildDefaultValidatorFactory());
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
答案 3 :(得分:2)
检查以下内容:
ApplicationFactory applicationFactory = (ApplicationFactory) FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
applicationFactory.getApplication().addDefaultValidatorId(BeanValidator.VALIDATOR_ID);
applicationFactory.getApplication().addValidator(BeanValidator.VALIDATOR_ID, BeanValidator.class.getName());