我正在使用primefaces 5.0开发jsf,如果在支持bean中满足条件,我需要将用户重定向到另一个页面。因此,我使用p:poll
让页面每秒钟检查一次条件,如果满足条件,则将用户重定向到另一个页面。
我创建了一个小项目来尝试这个场景,它使用poll来检查int cnt
是否>= 10,如果是,将用户重定向到welcomePrimefaces.xhtml
。此外,还有另一个线程T1
,它用于简单地增加cnt
,以便在某些时候满足条件。
这是我所做的:
Page:(没有什么特别的,只是每秒钟轮询一次检查状态)
<h:form>
Hello from Facelets
<br />
<p:poll interval="1" listener="#{mainBean.checkStatus()}"/>
</h:form>
Backing 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),在那之后,它被储存,甚至不执行轮询。
那么我的代码有什么问题呢?请帮帮我。
不要从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();
}