JSF 2.1重定向保存错误消息 [英] JSF 2.1 Redirect Preserving error message

查看:86
本文介绍了JSF 2.1重定向保存错误消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下commandButton动作方法处理程序:

I have the following commandButton action method handler:

public String reject()
{
  //Do something
  addMessage(null, "rejectAmountInvalid", FacesMessage.SEVERITY_ERROR);

  redirectToPortlet("/xxx/inbox?source=pendingActions#pendingApproval");
}

public static void addMessage(String clientId, String key, Severity level, Object... objArr)
{
    FacesContext context = FacesContext.getCurrentInstance();
    FacesMessage message = null;
    String msg = getTextFromResourceBundle(key);
    if (objArr != null && objArr.length > 0)
        msg = MessageFormat.format(msg, objArr);
    message = new FacesMessage(msg);

    message.setSeverity(level);
    context.addMessage(clientId, message);
}

public static void redirectToPortlet(String urlToRedirect)
{
    FacesContext context = FacesContext.getCurrentInstance();
    ExternalContext externalContext = context.getExternalContext();

    try
    {
        PortletRequest portletRequest = (PortletRequest) externalContext.getRequest();
        ThemeDisplay themeDisplay = (ThemeDisplay) portletRequest.getAttribute("THEME_DISPLAY");
        String portalURL = themeDisplay.getPortalURL();
        String redirect = portalURL + urlToRedirect;
        externalContext.redirect(redirect);
    }
    catch (Throwable e)
    {
        logger.log("Exception in redirectToPortlet to the URL: " + urlToRedirect, VLevel.ERROR, e);
    }
}

当页面重定向到"/xxx/inbox?source = pendingActions#pendingApproval"时,我添加的错误消息丢失了.有没有办法在JSF 2.1中保留错误消息?

When the page is redirected to "/xxx/inbox?source=pendingActions#pendingApproval", the error message I added is lost. Is there a way to preserve the error message in JSF 2.1?

谢谢 斯里

推荐答案

您可以使用PhaseListener保存下一个请求未显示的消息.

You can use a PhaseListener to save the messages that weren't displayed for the next request.

我使用林肯·巴克斯特(Lincoln Baxter)博客文章

I've been using for a while one from Lincoln Baxter's blog post Persist and pass FacesMessages over multiple page redirects, you just copy the class to some package and register on your faces-config.xml.

博客文章中没有明确提及,但是我假设代码是公共领域的,所以我在这里发布一个更独立的答案:

It's not mentioned explicitly in the blog post, but I'm assuming the code is public domain, so I am posting here for a more self-contained answer:

package com.yoursite.jsf;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;

/**
 * Enables messages to be rendered on different pages from which they were set.
 *
 * After each phase where messages may be added, this moves the messages
 * from the page-scoped FacesContext to the session-scoped session map.
 *
 * Before messages are rendered, this moves the messages from the
 * session-scoped session map back to the page-scoped FacesContext.
 *
 * Only global messages, not associated with a particular component, are
 * moved. Component messages cannot be rendered on pages other than the one on
 * which they were added.
 *
 * To enable multi-page messages support, add a <code>lifecycle</code> block to your
 * faces-config.xml file. That block should contain a single
 * <code>phase-listener</code> block containing the fully-qualified classname
 * of this file.
 *
 * @author Jesse Wilson jesse[AT]odel.on.ca
 * @secondaryAuthor Lincoln Baxter III lincoln[AT]ocpsoft.com 
 */
public class MultiPageMessagesSupport implements PhaseListener
{

    private static final long serialVersionUID = 1250469273857785274L;
    private static final String sessionToken = "MULTI_PAGE_MESSAGES_SUPPORT";

    public PhaseId getPhaseId()
    {
        return PhaseId.ANY_PHASE;
    }

    /*
     * Check to see if we are "naturally" in the RENDER_RESPONSE phase. If we
     * have arrived here and the response is already complete, then the page is
     * not going to show up: don't display messages yet.
     */
    // TODO: Blog this (MultiPageMessagesSupport)
    public void beforePhase(final PhaseEvent event)
    {
        FacesContext facesContext = event.getFacesContext();
        this.saveMessages(facesContext);

        if (PhaseId.RENDER_RESPONSE.equals(event.getPhaseId()))
        {
            if (!facesContext.getResponseComplete())
            {
                this.restoreMessages(facesContext);
            }
        }
    }

    /*
     * Save messages into the session after every phase.
     */
    public void afterPhase(final PhaseEvent event)
    {
        if (!PhaseId.RENDER_RESPONSE.equals(event.getPhaseId()))
        {
            FacesContext facesContext = event.getFacesContext();
            this.saveMessages(facesContext);
        }
    }

    @SuppressWarnings("unchecked")
    private int saveMessages(final FacesContext facesContext)
    {
        List<FacesMessage> messages = new ArrayList<FacesMessage>();
        for (Iterator<FacesMessage> iter = facesContext.getMessages(null); iter.hasNext();)
        {
            messages.add(iter.next());
            iter.remove();
        }

        if (messages.size() == 0)
        {
            return 0;
        }

        Map<String, Object> sessionMap = facesContext.getExternalContext().getSessionMap();
        List<FacesMessage> existingMessages = (List<FacesMessage>) sessionMap.get(sessionToken);
        if (existingMessages != null)
        {
            existingMessages.addAll(messages);
        }
        else
        {
            sessionMap.put(sessionToken, messages);
        }
        return messages.size();
    }

    @SuppressWarnings("unchecked")
    private int restoreMessages(final FacesContext facesContext)
    {
        Map<String, Object> sessionMap = facesContext.getExternalContext().getSessionMap();
        List<FacesMessage> messages = (List<FacesMessage>) sessionMap.remove(sessionToken);

        if (messages == null)
        {
            return 0;
        }

        int restoredCount = messages.size();
        for (Object element : messages)
        {
            facesContext.addMessage(null, (FacesMessage) element);
        }
        return restoredCount;
    }
}

然后,在您的faces-config.xml上:

<phase-listener>com.yoursite.jsf.MultiPageMessagesSupport</phase-listener>

这篇关于JSF 2.1重定向保存错误消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆