开发者

Ajax redirection from inside a JSF PhaseListener fails

My use case is the following: A JSF2 page has been displayed to the user. The page contains an Ajax-enabled button:

<p:commandButton value="#{msgs.reset}" process="@this"
   actionListener="#{reworkSearchMB.clearReworkSearch()}" tabindex="13"
   update="mainpanel messages" global="false"
   disabled="#{!userMB.hasAccessToViewRework() and !userMB.hasAccessToCreateOrUpdateRework()}"
/>

So, the user waits for a LONG time while the page is on the screen and the session expires. After that, the user presses the Ajax-enabled button.

What I want to happen is: redirect 开发者_运维百科the user to the login screen.

So, following Jim Driscoll's advice from http://weblogs.java.net/blog/2009/05/14/redirecting-jsf-20-ajax-request, I created a PhaseListener attached to the RESTORE_VIEW phase which checks whether the session has expired and, if so, redirects to the login page:

ExternalContext ectx = ctx.getExternalContext();
String newUrl =
ectx.encodeActionURL(ctx.getApplication().getViewHandler().getActionURL(ctx,
"/login.xhtml"));
try {
ectx.redirect(newUrl); // calls responseComplete() according to JavaDocs
} catch (IOException ex) {
throw new FacesException(ex);
}

When listening to beforePhase (RESTORE_VIEW), I get a NullPointerException:

SEVERE: java.lang.NullPointerException
at com.sun.faces.context.PartialViewContextImpl.createPartialResponseWriter(PartialViewContextImpl.java:434) ~[jsf-impl.jar:2.1.0-FCS]
at com.sun.faces.context.PartialViewContextImpl.access$300(PartialViewContextImpl.java:71) ~[jsf-impl.jar:2.1.0-FCS]
at com.sun.faces.context.PartialViewContextImpl$DelayedInitPartialResponseWriter.getWrapped(PartialViewContextImpl.java:575) ~[jsf-impl.jar:2.1.0-FCS]
at javax.faces.context.PartialResponseWriter.startDocument(PartialResponseWriter.java:115) ~[jsf-api.jar:2.1.0-FCS]
at org.primefaces.context.PrimePartialResponseWriter.startDocument(PrimePartialResponseWriter.java:103) ~[primefaces-2.2.1.jar:na]
at com.sun.faces.context.ExternalContextImpl.redirect(ExternalContextImpl.java:572) ~[jsf-impl.jar:2.1.0-FCS]
at com.argushealth.rework.phaselistener.SecurityPhaseListener.doRedirect(SecurityPhaseListener.java:80) ~[SecurityPhaseListener.class:na]
at com.argushealth.rework.phaselistener.SecurityPhaseListener.beforePhase(SecurityPhaseListener.java:42) ~[SecurityPhaseListener.class:na]
at com.sun.faces.lifecycle.Phase.handleBeforePhase(Phase.java:228) ~[jsf-impl.jar:2.1.0-FCS]
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:99) ~[jsf-impl.jar:2.1.0-FCS]
at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:113) [jsf-impl.jar:2.1.0-FCS]
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) [jsf-impl.jar:2.1.0-FCS]
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:409) [jsf-api.jar:2.1.0-FCS]
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1534) [web-core.jar:3.1]
at org.apache.catalina.core.ApplicationDispatcher.doInvoke(ApplicationDispatcher.java:787) [web-core.jar:3.1]
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:649) [web-core.jar:3.1]
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:483) [web-core.jar:3.1]
at org.apache.catalina.core.ApplicationDispatcher.doDispatch(ApplicationDispatcher.java:454) [web-core.jar:3.1]
at org.apache.catalina.core.ApplicationDispatcher.dispatch(ApplicationDispatcher.java:350) [web-core.jar:3.1]
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:300) [web-core.jar:3.1]
at com.argushealth.enterprise.security.web.spring.exception.AbstractExceptionHandler.handleException(AbstractExceptionHandler.java:44) [enterprise-security-web-spring-1.0.4.jar:na]
at com.argushealth.enterprise.security.web.spring.ui.ExceptionHandlingFilter.doFilterHttp(ExceptionHandlingFilter.java:57) [enterprise-security-web-spring-1.0.4.jar:na]
at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53) [spring-security-core-2.0.3.jar:2.0.3]
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:371) [spring-security-core-2.0.3.jar:2.0.3]
at org.springframework.security.util.FilterChainProxy.doFilter(FilterChainProxy.java:174) [spring-security-core-2.0.3.jar:2.0.3]
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:236) [spring-2.5.5.jar:2.5.5]
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167) [spring-2.5.5.jar:2.5.5]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256) [web-core.jar:3.1]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215) [web-core.jar:3.1]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279) [web-core.jar:3.1]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) [web-core.jar:3.1]
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655) [web-core.jar:3.1]
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595) [web-core.jar:3.1]
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98) [web-glue.jar:3.1]
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91) [web-glue.jar:3.1]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162) [web-core.jar:3.1]
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:326) [web-core.jar:3.1]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:227) [web-core.jar:3.1]
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:170) [kernel.jar:3.1]
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:822) [grizzly-http.jar:1.9.31]
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:719) [grizzly-http.jar:1.9.31]
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1013) [grizzly-http.jar:1.9.31]
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225) [grizzly-http.jar:1.9.31]
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137) [grizzly-framework.jar:1.9.31]
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104) [grizzly-framework.jar:1.9.31]
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90) [grizzly-framework.jar:1.9.31]
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79) [grizzly-http.jar:1.9.31]
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54) [grizzly-framework.jar:1.9.31]
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59) [grizzly-framework.jar:1.9.31]
at com.sun.grizzly.ContextTask.run(ContextTask.java:71) [grizzly-framework.jar:1.9.31]
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532) [grizzly-utils.jar:1.9.31]
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513) [grizzly-utils.jar:1.9.31]
at java.lang.Thread.run(Thread.java:619) [na:1.6.0_20]

Thank you Miguel Ping, it's very helpful. I read the article you provided and try to fix this bug. But I meet another problem when I write the code below:

// workaround for PrimeFaces
  new RequestContextImpl(ec);
  if (ec.getRequestParameterMap().containsKey(Constants.PARTIAL_PROCESS_PARAM)
    && !ec.getRequestParameterMap().get(Constants.PARTIAL_PROCESS_PARAM).equals("@all")) {
    fc.setViewRoot(new PartialViewRoot(new UIViewRoot()));
  }

There is compile error because I can't find the Class RequestContextImpl and PartialViewRoot in my primefaces jar file. I use primefaces-2.2.1. I found these two classes are existed in some previous versions but not in 2.2.x. And I copy the two classes from the version 2.0.0 into my own project, but it still doesn't work. Any ideas?


The NPE is a known bug within PrimeFaces. See this post: http://primefaces.prime.com.tr/forum/viewtopic.php?f=3&t=2335


Try this to set the view

UIViewRoot view = facesContext.getApplication().getViewHandler().createView(facesContext, "");
facesContext.setViewRoot(view); 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜