使用带有 JSF 和 Omnifaces 的 Bean 验证的重复消息
Duplicated messages using Bean Validation with JSF and Omnifaces
我在使用客户端验证的 JSF 2.2、Omnifaces 2.6.3 和 PrimeFaces 6.1 时遇到问题,导致来自 Bean Validation 的验证消息显示两次。
如果我在某个按钮中使用
<p:commandButton value="Some Action" ajax="false" action="#{someController.action}" validateClient="false"> <!-- validation disabled to test server side validation -->
<o:validateBean value="#{someController.bean}" showMessageFor="@violating" />
</p:commandButton>
验证有效,但每次验证都会产生两条消息:
NotNull validation failed
NotNull validation failed
Max validation failed
Max validation failed
我追踪到问题是 class javax.faces.validator.BeanValidator 与 Omnifaces org.omnifaces.taghandler.ValidateBean 一起执行验证.
我试图删除 JSF 的默认 bean 验证,但 PrimeFaces 客户端验证依赖于启用将 validatorIds 发送到客户端,所以它不是一个选项。
我做了一个解决方法,在注释中使用一些组,默认的 BeanValidator 不会验证,但我想知道是否有一种方法可以不强制使用组。
谢谢!
编辑:
示例项目 https://github.com/marcelopio/duplicatederror
编辑 2:
SomeController.class
@Named
@ViewScoped
public class SomeController implements Serializable {
private static final long serialVersionUID = 6184842672181799938L;
private Foo foo = new Foo();
public void someAction() {
System.out.println("action");
}
public Foo getFoo() {
return foo;
}
public void setFoo(Foo foo) {
this.foo = foo;
}
}
Foo.class
public class Foo implements Serializable {
private static final long serialVersionUID = -7334434752280744719L;
@Max(5)
private Integer bar;
public Integer getBar() {
return bar;
}
public void setBar(Integer bar) {
this.bar = bar;
}
}
XHTML
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:o="http://omnifaces.org/ui">
<h:head>
<title>Teste</title>
</h:head>
<h:body>
<h:form>
<p:messages />
<p:outputLabel value="Bar" for="bar"/>
<p:inputText id="bar" value="#{someController.foo.bar}" />
<p:message for="bar" />
<p:commandButton value="Action" action="#{someController.someAction()}" ajax="false" validateClient="false">
<o:validateBean value="#{someController.foo}" showMessageFor="@violating" />
</p:commandButton>
</h:form>
</h:body>
</html>
WEB.XML
<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">
<display-name>Duplicated Error</display-name>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<context-param>
<param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>primefaces.TRANSFORM_METADATA</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>primefaces.CLIENT_SIDE_VALIDATION</param-name>
<param-value>true</param-value>
</context-param>
<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>
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
<welcome-file-list>
<welcome-file>initial.xhtml</welcome-file>
</welcome-file-list>
</web-app>
使用 showMessageFor=""
属性控制消息的显示方式 o:validateBean 同时还将 p:messaages
的 globalOnly
属性设置为 true
。
已更新
对于您的用例,o:messages 提供了这样做的可能性:
例如
<o:messages for="fooBar" />
<h:form id="fooBar">
<p:outputLabel value="Bar" for="bar"/>
<p:inputText id="bar" value="#{someController.foo.bar}" />
<p:message for="bar" />
<p:outputLabel value="Bar" for="foo"/>
<p:inputText id="foo" value="#{someController.foo.bar}" />
<p:message for="foo" />
</h:form>
如上所述,您的消息会在两个级别显示。
我在使用客户端验证的 JSF 2.2、Omnifaces 2.6.3 和 PrimeFaces 6.1 时遇到问题,导致来自 Bean Validation 的验证消息显示两次。
如果我在某个按钮中使用
<p:commandButton value="Some Action" ajax="false" action="#{someController.action}" validateClient="false"> <!-- validation disabled to test server side validation -->
<o:validateBean value="#{someController.bean}" showMessageFor="@violating" />
</p:commandButton>
验证有效,但每次验证都会产生两条消息:
NotNull validation failed
NotNull validation failed
Max validation failed
Max validation failed
我追踪到问题是 class javax.faces.validator.BeanValidator 与 Omnifaces org.omnifaces.taghandler.ValidateBean 一起执行验证.
我试图删除 JSF 的默认 bean 验证,但 PrimeFaces 客户端验证依赖于启用将 validatorIds 发送到客户端,所以它不是一个选项。
我做了一个解决方法,在注释中使用一些组,默认的 BeanValidator 不会验证,但我想知道是否有一种方法可以不强制使用组。
谢谢!
编辑: 示例项目 https://github.com/marcelopio/duplicatederror
编辑 2:
SomeController.class
@Named
@ViewScoped
public class SomeController implements Serializable {
private static final long serialVersionUID = 6184842672181799938L;
private Foo foo = new Foo();
public void someAction() {
System.out.println("action");
}
public Foo getFoo() {
return foo;
}
public void setFoo(Foo foo) {
this.foo = foo;
}
}
Foo.class
public class Foo implements Serializable {
private static final long serialVersionUID = -7334434752280744719L;
@Max(5)
private Integer bar;
public Integer getBar() {
return bar;
}
public void setBar(Integer bar) {
this.bar = bar;
}
}
XHTML
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:o="http://omnifaces.org/ui">
<h:head>
<title>Teste</title>
</h:head>
<h:body>
<h:form>
<p:messages />
<p:outputLabel value="Bar" for="bar"/>
<p:inputText id="bar" value="#{someController.foo.bar}" />
<p:message for="bar" />
<p:commandButton value="Action" action="#{someController.someAction()}" ajax="false" validateClient="false">
<o:validateBean value="#{someController.foo}" showMessageFor="@violating" />
</p:commandButton>
</h:form>
</h:body>
</html>
WEB.XML
<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">
<display-name>Duplicated Error</display-name>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<context-param>
<param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>primefaces.TRANSFORM_METADATA</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>primefaces.CLIENT_SIDE_VALIDATION</param-name>
<param-value>true</param-value>
</context-param>
<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>
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
<welcome-file-list>
<welcome-file>initial.xhtml</welcome-file>
</welcome-file-list>
</web-app>
使用 showMessageFor=""
属性控制消息的显示方式 o:validateBean 同时还将 p:messaages
的 globalOnly
属性设置为 true
。
已更新
对于您的用例,o:messages 提供了这样做的可能性:
例如
<o:messages for="fooBar" />
<h:form id="fooBar">
<p:outputLabel value="Bar" for="bar"/>
<p:inputText id="bar" value="#{someController.foo.bar}" />
<p:message for="bar" />
<p:outputLabel value="Bar" for="foo"/>
<p:inputText id="foo" value="#{someController.foo.bar}" />
<p:message for="foo" />
</h:form>
如上所述,您的消息会在两个级别显示。