Как перенаправить с помощью опроса primefaces?

#jsf #redirect #jsf-2 #primefaces #polling

#jsf #перенаправление #jsf-2 #primefaces #опрос

Вопрос:

Я разрабатываю jsf с primefaces 5.0, мне нужно перенаправить пользователя на другую страницу, если выполняется условие в вспомогательном компоненте. Поэтому я использую p:poll , чтобы страница проверяла условие каждую секунду, и если условие выполнено, перенаправляю пользователя на другую страницу.

Я создаю небольшой проект, чтобы попробовать этот сценарий, который использует опрос, чтобы проверить, int cnt является ли >= 10, если да, перенаправить пользователя на welcomePrimefaces.xhtml . Кроме того, есть другой поток, T1 который используется для простого увеличения, cnt чтобы условие могло выполняться некоторое время.

Вот что я сделал:
Страница:(Ничего особенного, просто опрашивайте каждую секунду, чтобы проверить статус)

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

Резервный компонент:

 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:

Отправляйте перенаправление не из 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 amp;amp;
            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();

}
  

Комментарии:

1. «Не усложняйте себя», это именно то, что вы сделали, я полагаю.

2. @SujanSivagurunathan, ответ — это первый фрагмент кода. Второй фрагмент кода принадлежит реализации Mojarra, я прикрепил его просто для того, чтобы показать, чем он отличается между ajax- и не-ajax-запросами.

3. тогда это самый короткий возможный ответ. Извините, я думал, что метод перенаправления был вашей собственной реализацией.

4. Спасибо @Xtreme Biker. Итак, когда я вызвал redirect метод в моем checkStatus , он фактически повторно отобразил всю страницу, верно? Если да, изменится ли URL-адрес?

5. @nosnhoj перенаправление всегда изменяет URL в адресной строке браузера. То, что вы здесь делаете, следует шаблону POST-REDIRECT-GET .