如何在不同Faceslets消息组件上分别显示对应消息?
问题分析
你遇到的问题核心是:h:messages组件默认会渲染所有Faces消息,不管消息关联的客户端ID,所以点击按钮后两个消息组件都会显示所有消息。要实现消息分开展示,需要指定每个消息组件只显示关联到特定客户端ID的消息。
解决方案
以下两种方式都可以实现需求:
方式一:使用h:message(单条消息组件,推荐)
这种方式更贴合"单个组件对应单条消息"的场景,代码更清晰:
- 修改
index.html,添加表单ID、虚拟消息目标组件,并替换h:messages为h:message并指定for属性:
<!DOCTYPE HTML> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:f="http://xmlns.jcp.org/jsf/core"> <h:head> <title>Index</title> </h:head> <h:body> <!-- 给表单设置固定ID,避免客户端ID动态变化 --> <h:form id="myForm"> msg001: <h:message id="msg001" for="msgTarget001" style="color: #2ecc71;" /> msg002: <h:message id="msg002" for="msgTarget002" style="color: #3498db;" /> <h:commandButton id="btn001" value="Trigger msg001" action="#{testFaces.callMsg001()}"> </h:commandButton> <h:commandButton id="btn002" value="Trigger msg002" action="#{testFaces.callMsg002()}"> </h:commandButton> <!-- 隐藏的虚拟组件,作为消息关联的目标ID --> <h:inputHidden id="msgTarget001" style="display: none;" /> <h:inputHidden id="msgTarget002" style="display: none;" /> </h:form> </h:body> </html>
- 修改
TestFaces.java,指定消息关联的完整客户端ID(表单ID + 冒号 + 目标组件ID):
import javax.faces.application.FacesMessage; import javax.faces.context.FacesContext; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @javax.enterprise.context.RequestScoped @javax.inject.Named public class TestFaces implements java.io.Serializable { static final long serialVersionUID = 1L; static final Logger logger = LogManager.getLogger(); public String callMsg001() { // 关联到表单内的msgTarget001组件 FacesContext.getCurrentInstance().addMessage("myForm:msgTarget001", new FacesMessage(FacesMessage.SEVERITY_INFO, "This is msg001", null)); return null; } public String callMsg002() { // 关联到表单内的msgTarget002组件 FacesContext.getCurrentInstance().addMessage("myForm:msgTarget002", new FacesMessage(FacesMessage.SEVERITY_INFO, "This is msg002", null)); return null; } }
方式二:给h:messages添加for属性(多条消息场景)
如果需要在一个组件内显示多条同类型消息,可以给h:messages添加for属性限制显示范围,代码修改如下:
- 修改
index.html:
<h:form id="myForm"> msg001: <h:messages id="msg001" for="msgTarget001" style="color: #2ecc71;" /> msg002: <h:messages id="msg002" for="msgTarget002" style="color: #3498db;" /> <!-- 按钮和隐藏组件同方式一 --> </h:form>
- Java代码和方式一完全一致。
补充说明
- 表单设置固定ID是为了避免JSF自动生成动态ID,导致消息关联的客户端ID匹配失败;
- 隐藏的
h:inputHidden是为了提供一个稳定的组件ID作为消息关联目标,你也可以直接关联到按钮ID(比如把addMessage的参数改为myForm:btn001,h:message的for改为btn001); - 原代码中
style="msg001"是错误写法,style属性需要写CSS样式声明(如color: red;),如果要使用CSS类名,应该用styleClass="msg001"。
内容的提问来源于stack exchange,提问作者Error 404
相关产品推荐
相关产品推荐

