You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击p:commandButton跳转后p:growl无法显示消息的问题

解决p:commandButton跳转后p:growl不显示消息的问题

我来帮你拆解下这个问题的核心:你通过action方法导航页面后,无论是forward还是redirect,添加的FacesMessage都没法正常显示在p:growl里,对吧?结合你给出的代码和尝试的方案,我来给你梳理问题原因和可行的解决方案。

问题根源分析

  1. Forward场景:当你返回homePage.xhtml做forward时,消息存在当前请求的FacesContext中,但forward后页面会被目标页面完全替换——而你的目标页面homePage.xhtml里根本没有p:growl组件,自然看不到消息;另外你设置了ajax="false",整页刷新后原页面的p:growl也会被销毁。
  2. Redirect场景:默认FacesMessage不会跨请求保留,即使你用了Flash,若没正确配置跳转方式或目标页面没有p:growl,消息也无法显示。

可行解决方案

方案1:Redirect + Flash + 目标页面添加p:growl

这是最可靠的跨页面显示消息的方式,步骤如下:

第一步:给目标页面homePage.xhtml添加p:growl

在目标页面的form里加入p:growl组件,让消息有显示的载体:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<h:form id="form">
    <p:growl id="growl" /> <!-- 新增这一行 -->
    <!-- 其他原有代码 -->
</h:form>
</html>

第二步:修改ManagedBean的action方法,正确使用Flash并跳转

先设置Flash保留消息,再添加消息,最后用redirect方式跳转(通过?faces-redirect=true实现):

@ViewScoped
@ManagedBean
public class ForwardPageBean implements Serializable{
    private static final long serialVersionUID = 1L;

    public String forward(){
        FacesContext context = FacesContext.getCurrentInstance();
        ExternalContext externalContext = context.getExternalContext();
        // 先设置Flash保留消息,这一步必须在添加消息之前
        Flash flash = externalContext.getFlash();
        flash.setKeepMessages(true);
        
        // 添加消息
        context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Random message", null));
        
        // 使用redirect跳转,确保消息能通过Flash带到新请求
        return "homePage.xhtml?faces-redirect=true";
    }
}

第三步:保持commandButton的配置不变

你的按钮配置没问题,ajax="false"配合redirect是正常的整页刷新逻辑:

<p:commandButton value="Simple Button" 
                 action="#{forwardPageBean.forward()}" 
                 update=":form:growl" 
                 ajax="false" />

方案2:Forward场景(仅同请求内导航)

如果你的业务场景必须用forward(不做redirect),只需要确保目标页面有p:growl即可,因为forward是同一个请求,FacesMessage会保留在当前请求的上下文里:

  • 目标页面按方案1添加p:growl;
  • ManagedBean返回"homePage.xhtml"(不需要加?faces-redirect=true);
  • 这种方式不需要用Flash,因为是同一个请求。

为什么你之前的尝试失败?

  • 用Flash但没加redirect:Flash是为跨请求(redirect)设计的,forward是同请求,Flash不起作用,且目标页面没有p:growl;
  • actionListener能显示消息:因为actionListener不触发导航,页面没刷新,原页面的p:growl还在,所以能看到,但无法实现页面跳转;
  • 同时用actionListener和action:action做了redirect,但目标页面没有p:growl,消息虽然被Flash带到了新请求,但没有载体显示。

内容的提问来源于stack exchange,提问作者sohs3411

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:14:16