如何使用primefaces轮询重定向?

时间:2014-07-07 09:01:24

标签: jsf redirect jsf-2 primefaces polling

我正在使用primefaces 5.0开发jsf,如果在backing bean中满足条件,我需要将用户重定向到另一个页面。所以我使用p:poll让页面每秒检查一次条件,如果满足条件,则将用户重定向到另一个页面。

我创建了一个小项目来尝试这种情况,使用民意调查检查int cnt是否> = 10,如果是,则将用户重定向到welcomePrimefaces.xhtml。此外,还有另一个线程T1,用于简单地增加cnt,以便条件可以满足一段时间。

这就是我所做的:
页面(没有什么特别的,只需每秒轮询以查看状态)

<h:form>
    Hello from Facelets
    <br />
    <p:poll interval="1" listener="#{mainBean.checkStatus()}"/>
</h:form>

支持Bean:

public class MainBean {

    private Integer cnt = 0;

    @PostConstruct
    public void init() {
        Thread t1 = new Thread(new T1(), "test");
        t1.start();

    }

    public void checkStatus() {
        synchronized (cnt) {
            System.out.println("cnt:" + cnt);
            if (cnt >= 10) {
                try {
                    Object request = FacesContext.getCurrentInstance().getExternalContext().getRequest();
                    Object response = FacesContext.getCurrentInstance().getExternalContext().getResponse();
                    HttpServletRequest httpRequest = (HttpServletRequest) request;
                    HttpServletResponse httpResponse = (HttpServletResponse) response;
                    httpResponse.sendRedirect(httpRequest.getContextPath()
                            + "/welcomePrimefaces.xhtml");
                } catch (IOException ex) {
                    System.out.println("Error!");
                }
            }
        }
    }

    private class T1 implements Runnable {

        @Override
        public void run() {
            try {
                while (true) {
                    Thread.sleep(1000);
                    synchronized (cnt) {
                        cnt++;
                    }
                }
            } catch (InterruptedException ex) {
                System.out.println("Thread Error!");
            }
        }
    }
}

结果是cnt被打印10次(从0到9),之后,它被存货,甚至没有执行轮询。
那我的代码出了什么问题?请帮帮我 提前谢谢。

1 个答案:

答案 0 :(得分:5)

不要从Http响应发送重定向,而是从外部上下文本身发送:

FacesContext.getCurrentInstance().getExternalContext()
        .redirect("welcomePrimefaces.xhtml");

如果请求不是部分的(Ajax),您的代码将正常工作。 Mojarra JSF包装器处理这两种情况,因此只需使用它,不要过度复杂化。这里有Mojarra 2.1.28中的内部实现:

<强> ExternalContextImpl.java

/**
 * @see ExternalContext#redirect(String)
 */
public void redirect(String requestURI) throws IOException {

    FacesContext ctx = FacesContext.getCurrentInstance();
    getELFlash().doLastPhaseActions(ctx, true);

    if (ctx.getPartialViewContext().isPartialRequest()) {
        //Handle partial request returning a redirection code in XML format
        if (getSession(true) instanceof HttpSession &&
            ctx.getResponseComplete()) {
            throw new IllegalStateException();
        }
        PartialResponseWriter pwriter;
        ResponseWriter writer = ctx.getResponseWriter();
        if (writer instanceof PartialResponseWriter) {
            pwriter = (PartialResponseWriter) writer;
        } else {
            pwriter = ctx.getPartialViewContext().getPartialResponseWriter();
        }
        setResponseContentType("text/xml");
        setResponseCharacterEncoding("UTF-8");
        addResponseHeader("Cache-Control", "no-cache");
        pwriter.startDocument();
        pwriter.redirect(requestURI);
        pwriter.endDocument();
    } else {
        //Standard redirection behaviour
        ((HttpServletResponse) response).sendRedirect(requestURI);
    }
    ctx.responseComplete();

}