#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 .