【问题标题】:How to Redirect with primefaces polling?如何使用primefaces轮询重定向?
【发布时间】:2014-07-07 09:01:24
【问题描述】:

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

我创建了一个小项目来尝试这个场景,它使用 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),之后,它被库存,甚至没有执行轮询。
那么我的代码有什么问题?请帮帮我。
提前致谢。

【问题讨论】:

    标签: jsf redirect jsf-2 primefaces polling


    【解决方案1】:

    不要从 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();
    
    }
    

    【讨论】:

    • “不要让自己过于复杂”,这正是我所相信的。
    • @SujanSivagurunathan,答案是第一个代码片段。第二段代码属于 Mojarra 实现,我附上它只是为了说明 ajax 和非 ajax 请求之间的区别。
    • 那么这是最短的答案。抱歉,我以为重定向方法是你自己实现的。
    • 谢谢@Xtreme Biker。所以当我在checkStatus 中调用redirect 方法时,它实际上会重新渲染整个页面,对吧?如果是这样,URL会改变吗?
    • @nosnhoj 重定向总是会更改浏览器地址栏中的 url。您在此处所做的操作遵循POST-REDIRECT-GET pattern
    猜你喜欢
    • 2012-05-02
    • 1970-01-01
    • 2014-07-20
    • 2021-11-21
    • 2014-10-28
    • 2023-03-07
    • 2012-06-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多