注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

流星永恒的博客

JSF,Facelets,Rich(Prime)Faces,和java的笔记

 
 
 

日志

 
 

Message Handling with JSF and Redirects(updated--when use ajax the message show twice)  

2010-05-08 22:18:09|  分类: jsf |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

 

      If you add several faces messages to facescontext and return a outcome which configed to redirect to another page,   you'll find that at next page, you can't get these messages and show them on the page, because jsf messages contains in request, after redirecting, there is a new request generated, so messages in the old request are lost. How keep them in the new reqeust? Obviously, by the http session to keep them;

     Here is a solution. (Found in Internet)

1. Provide a PhaseListener.

package com.util;

 

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.
 * To produce this behaviour, this class acts as a
 * <code>PhaseListener</code>.
 *
* This is performed by moving the FacesMessage objects: <li>After each phase
 * where messages may be added, this moves the messages from the page-scoped
 * FacesContext to the session-scoped session map. <li>Before messages are
 * rendered, this moves the messages from the session-scoped session map back to
 * the page-scoped FacesContext.
 *
* Only messages that are not associated with a particular component are ever
 * moved. These are the only messages that can be rendered on a page that is
 * different from where they originated.
 *
* To enable this behaviour, 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 <a href="Jesse'>mailto:jesse@odel.on.ca">Jesse Wilson</a>
 */
public class MessageHandler implements PhaseListener {

    /**
     *
     */
    private static final long serialVersionUID = 1L;
    /**
     * a name to save messages in the session under
     */
    private static final String sessionToken = "MULTI_PAGE_MESSAGES_SUPPORT";
    private static final String redirectToken = "MULTI_PAGE_MESSAGES_REDIRECT";

    /**
     * Return the identifier of the request processing phase during which this
     * listener is interested in processing PhaseEvent events.
     */
    public PhaseId getPhaseId() {
        return PhaseId.ANY_PHASE;
    }

    /**
     * Handle a notification that the processing for a particular phase of the
     * request processing lifecycle is about to begin.
     */
    public void beforePhase(PhaseEvent event) {

        if (event.getPhaseId() == PhaseId.RENDER_RESPONSE) {
            FacesContext facesContext = event.getFacesContext();
            restoreMessages(facesContext);
        }
    }

    /**
     * Handle a notification that the processing for a particular phase has just
     * been completed.
     */
    public void afterPhase(PhaseEvent event) {
        FacesContext facesContext = event.getFacesContext();
        if (PhaseId.RESTORE_VIEW.equals(event.getPhaseId())) {
            Map<String, Object> sessionMap = facesContext.getExternalContext().getSessionMap();
            Integer m = (Integer) sessionMap.get(redirectToken);
            if (null == m) {
                sessionMap.put(redirectToken, 0);
            } else if (m == 0) {
                sessionMap.put(redirectToken, 1);
            } else if (m == 1) {
                sessionMap.put(redirectToken, 0);
            }
        }

        if (event.getPhaseId() == PhaseId.APPLY_REQUEST_VALUES
                || event.getPhaseId() == PhaseId.PROCESS_VALIDATIONS
                || event.getPhaseId() == PhaseId.INVOKE_APPLICATION) {

            saveMessages(facesContext);
        }

    }

    /**
     * Remove the messages that are not associated with any particular component
     * from the faces context and store them to the user's session.
     *    
* @return the number of removed messages.
     */
    @SuppressWarnings("unchecked")
    private int saveMessages(FacesContext facesContext) {
// remove messages from the context
        List<FacesMessage> messages = new ArrayList<FacesMessage>();
        for (Iterator<FacesMessage> i = facesContext.getMessages(null); i.hasNext();) {//*********#1  Note "null"   *****//

//*********Just store faces messages with the null value clientid ,if the clientId of messages were not null,***********//
//*******will not store; You can modify here to store them********//

            messages.add((FacesMessage) i.next());
            i.remove();
        }
        // store them in the session
        if (messages.size() == 0) {
            return 0;
        }
        Map<String, Object> sessionMap = facesContext.getExternalContext().getSessionMap();
        // if there already are messages
        List<FacesMessage> existingMessages = (List<FacesMessage>) sessionMap.get(sessionToken);
        if (existingMessages != null) {
            existingMessages.addAll(messages);
        } else {
            sessionMap.put(sessionToken, messages); // if these are the first messages
        }

        return messages.size();
    }

    /**
     * Remove the messages that are not associated with any particular component
     * from the user's session and add them to the faces context.
     *    
* @return the number of removed messages.
     */
    @SuppressWarnings("unchecked")
    private int restoreMessages(FacesContext facesContext) {
        // remove messages from the session
        Map sessionMap = facesContext.getExternalContext().getSessionMap();
        Integer m = (Integer) sessionMap.get(redirectToken);
        List messages = (List) sessionMap.remove(sessionToken);
        sessionMap.put(redirectToken, 0);
        if (m == 1) { //not redirect--ajax request
            return 0;
        } else { //redirect request
            // store them in the context
            if (messages == null) {
                return 0;
            }
            int restoredCount = messages.size();
            for (Iterator i = messages.iterator(); i.hasNext();) {
                facesContext.addMessage(null, (FacesMessage) i.next());
            }
            return restoredCount;
        }
    }
}


2. config the listener in faces-config.xml

...

 <lifecycle>
<phase-listener>com.util.MessageHandler</phase-listener>
</lifecycle>

...

3. Add messages to facesContex in an action

 public String nextPage() {
  JSFUtil.addSuccessMessage("Your messages");

/*     

   FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO,
                msg, msg);
        FacesContext fc = FacesContext.getCurrentInstance();
        fc.addMessage(null, facesMsg);    //********#2 Note "null"**************//

*/
  return "nextPage";
 }

4. Config page flow

 <navigation-rule>
  <from-view-id>/index.xhtml</from-view-id>
  <navigation-case>
   <from-outcome>nextPage</from-outcome>
   <to-view-id>/next.xhtml</to-view-id>
   <redirect/>
  </navigation-case>
 </navigation-rule>

5 .Note line #1 and #2

6. OK!

  评论这张
 
阅读(964)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018