JSF 2.0登录验证中的非法状态异常。为什么?

时间:2011-03-15 06:18:11

标签: jsf login jsf-2

我尝试重定向直接输入主页网址但未登录的用户。

所以我将此活动附加到主页。

<f:metadata>
       <f:event type="preRenderView" listener="#{login_bean.verifyAccessOut}"/>
</f:metadata>

在login_bean里面我有这个方法......

public void verifyAccessOut() {

    ExternalContext context2 = FacesContext.getCurrentInstance().getExternalContext();
        if(logstatus==false)
        try {
            message="Unauthorized Access: Please Login First";
            style="color:red;text-decoration:blink";
            context2.redirect("index.xhtml");
    } catch (IOException ex) {
        Logger.getLogger(HomeBean.class.getName()).log(Level.SEVERE, null, ex);
    }
}

它抛出了一个非法的状态异常。像这样,

WARNING: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
java.lang.IllegalStateException
    at org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:522)
    at com.sun.faces.context.ExternalContextImpl.redirect(ExternalContextImpl.java:572)
    at org.mit.care.LoginBean.verifyAccessIn(LoginBean.java:48)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.sun.el.parser.AstValue.invoke(AstValue.java:234)
    at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:297)
    at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:43)
    at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:72)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:98)
    at com.sun.faces.facelets.tag.jsf.core.DeclarativeSystemEventListener.processEvent(EventHandler.java:118)
    at javax.faces.component.UIComponent$ComponentSystemEventListenerAdapter.processEvent(UIComponent.java:2345)
    at javax.faces.event.SystemEvent.processListener(SystemEvent.java:102)
    at com.sun.faces.application.ApplicationImpl.processListeners(ApplicationImpl.java:1993)
    at com.sun.faces.application.ApplicationImpl.invokeComponentListenersFor(ApplicationImpl.java:1941)
    at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:285)
    at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:243)
    at javax.faces.application.Application.publishEvent(Application.java:1660)
    at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:114)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:313)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:343)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)
    at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:277)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
    at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:332)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:233)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:165)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
    at java.lang.Thread.run(Thread.java:662)

为什么会这样?为什么我不能使用外部上下文重定向到prerender视图事件的必要页面?

请帮我理解这个问题。谢谢....

1 个答案:

答案 0 :(得分:1)

视图不是控制请求的正确位置。更改响应可能为时已晚,因为视图本身是响应的一部分。在执行此代码行时,最终用户已经从服务器获得了一部分响应。这是一个不归路。服务器无法获取已发送的响应并发送另一个响应。在任何位被发送到响应之前,您需要完成的工作。

您通常会使用Filter,它在请求的最初阶段运行。将所有受限制的网页放在某个文件夹中,例如/private/*/secured/*/app/*或其他任何内容,并在该网址格式上映射Filter,该格式在{{doFilter()执行以下作业1}}方法:

if (((HttpServletRequest) request).getSession().getAttribute("user") == null) {
    ((HttpServletResponse) response).sendRedirect("/home");
} else {
    chain.doFilter(request, response);
}

此示例假定已登录用户作为名为user的会话属性存在。它甚至可以是一个会话作用域的JSF托管bean。