Primefaces自定义Validator校验消息无法在growl、messages中正常显示
问题根因
- 自定义Validator处理逻辑不规范:仅调用
FacesContext.addMessage()添加消息但未抛出ValidatorException时,JSF会判定校验通过,继续执行后续生命周期阶段,后续触发的组件自动更新会清除刚添加的临时消息。 - 多消息组件配置冲突:同时启用
p:growl和p:messages的autoUpdate="true",且未添加消息过滤规则,Primefaces 3.4.1版本存在该场景下消息生命周期处理异常的已知问题,即使配置sticky="true"也会失效。
可行解决方案
步骤1:修正自定义Validator写法
校验不通过时直接构造消息抛出ValidatorException即可,无需手动调用addMessage,JSF会自动完成消息注册:
@Override public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { Integer inputVal = (Integer) value; // 替换为你实际的校验逻辑 if (inputVal < 1 || inputVal > 100) { FacesMessage errorMsg = new FacesMessage("数值校验失败", "请输入1-100范围内的整数"); errorMsg.setSeverity(FacesMessage.SEVERITY_ERROR); throw new ValidatorException(errorMsg); } }
步骤2:调整消息组件配置,避免冲突
根据你的使用场景二选一即可:
方案A:保留双消息组件,添加消息过滤规则
给两个组件添加globalOnly属性区分消息展示范围,避免重复处理同一条消息:
<!-- 模板growl:仅展示全局无绑定组件的消息 --> <p:growl id="msgs" autoUpdate="true" showDetail="true" globalOnly="true" sticky="true" /> <!-- 页面messages:仅展示绑定到具体字段的校验消息 --> <p:messages id="messages" autoUpdate="true" closable="true" showDetail="true" globalOnly="false" />
方案B:关闭冗余组件的autoUpdate
如果不需要同时在两处展示校验消息,直接关闭其中一个组件的自动更新即可,比如关闭p:messages的autoUpdate:
<p:messages id="messages" autoUpdate="false" closable="true" showDetail="true" />
可选优化:关闭autoUpdate手动指定更新时机
如果页面存在大量无关ajax请求会触发自动更新,可以关闭两个组件的autoUpdate,在提交按钮的update属性中手动指定需要更新的消息组件,避免消息被意外清空:
<p:growl id="msgs" autoUpdate="false" showDetail="true" sticky="true" /> <p:messages id="messages" autoUpdate="false" closable="true" showDetail="true" /> <!-- 提交按钮指定更新消息组件 --> <p:commandButton value="提交" action="#{yourBean.submit}" update="msgs messages" />
内容的提问来源于stack exchange,提问作者Marco Sulla
相关产品推荐
相关产品推荐

