当前位置: 首页 > 知识库问答 >
问题:

根据用户权限,在preRenderViewEvent中导航到其他页面;ExternalContext#dispatch()不起作用

丘友樵
2023-03-14

只有当用户有权限查看该页面时,才应该呈现该页面。我试图通过在PreRenderView事件监听器方法中执行检查来实现这一点:

<f:event type="preRenderView" listener="#{theBean.init}" />

方法本身:

public void init() {
    if (user.havePermission()) {
        // backing bean init
    } else {
        FacesContext fc = FacesContext.getCurrentInstance();
        ExternalContext ec = fc.getExternalContext();
        ec.getRequestMap().put("message", no_permissions_message);
        try {
            ec.dispatch(ec.getRequestContextPath()
                + path_to_no_perm_page);
            fc.responseComlete();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

当我试图查看被拒绝的页面时,我看到了它,但在服务器日志中出现了异常:

at org.omnifaces.util.FacesLocal.getRequestMap(FacesLocal.java:945) [omnifaces-1.7.jar:1.7]
at org.omnifaces.util.FacesLocal.getRequestAttribute(FacesLocal.java:953) [omnifaces-1.7.jar:1.7]
at org.omnifaces.util.Faces.getRequestAttribute(Faces.java:1416) [omnifaces-1.7.jar:1.7]
at org.omnifaces.eventlistener.CallbackPhaseListener.getCallbackPhaseListeners(CallbackPhaseListener.java:110) [omnifaces-1.7.jar:1.7]
at org.omnifaces.eventlistener.CallbackPhaseListener.afterPhase(CallbackPhaseListener.java:77) [omnifaces-1.7.jar:1.7]
at com.sun.faces.lifecycle.Phase.handleAfterPhase(Phase.java:189) [jsf-impl-2.1.7-jbossorg-2.jar:]
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:107) [jsf-impl-2.1.7-jbossorg-2.jar:]
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139) [jsf-impl-2.1.7-jbossorg-2.jar:]
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:98) [primefaces-4.0.7.jar:4.0.7]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
at org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
...

原因:在调度调用后,FacesC立即返回nullontext.getMONtInstance()。但这不会中断当前阶段。因此在相位结束时PhaseListener被执行。它试图获取FacesContext实例,但获取为空。

我可以在这里避免执行PhaseListener吗?或者可能是检查FacesContext当前实例不为null是否应添加到omnifaces?

谢谢

共有1个答案

鄢开诚
2023-03-14

永远不要使用ExternalContext#dispatch()。在一个像样的JSF web应用程序中,这种方法没有一个合理的用例。它只会破坏JSF的生命周期,因为它会在当前请求中创建另一个FacesContext。您应该使用JSF自己的NavigationHandler或使用ExternalContext#redirect()

当您已经使用JSF 2.2时,请使用

public String init() {
    // ...
    return "someViewId";
}

或者当您仍然使用JSF 2.0/2.1时,因此只能使用

public void init() {
    // ...
    Faces.navigate("someViewId");
}

如果您没有使用OmniFaces,以下是它的实现方式:

public void init() {
    // ...
    FacesContext context = FacesContext.getCurrentInstance();
    context.getApplication().getNavigationHandler().handleNavigation(context, null, "someViewId");
}

请注意,当使用@PostConstruct而不是f: viewActionpreRenderView时,这一切仍然可能失败。另见a. o.@PostConstruct中的重定向会导致IllegalStateExc农田异常

 类似资料:
  • 我有两个页面:home.jsp和stylechoosertable.jsp。jsp有一个指向stylechoosertable.jsp的简单链接。两者都在src-main-webapp-views中。启动应用程序运行良好,加载home.jsp也很好。然而,当我点击链接时,它会转到一个404未找到的页面。 下面是HomeController.java > 仅本地:8080/MySpringMVC/打

  • 我的导航有问题。这是我的导航码。 我创建了三个堆栈,如AppStack、StartStack和AuthStack。这些是在createAppContainer()函数中使用的,希望访问这些 this.props.navigation.navigate('App') ... 我可以访问 this.props.navigation.navigate(开始) 和 this.props.navigatio

  • Iam正在使用ionic应用程序编辑配置文件和查看配置文件。编辑编辑页面的详细信息后,它将导航到查看配置文件页面。 我希望在导航后刷新查看配置文件页面。 这是editprofile.ts代码: 首先我用下面的导航 通过谷歌搜索,我添加了这个来在导航后刷新视图配置文件 现在发生的是,首先它被重定向到查看个人资料页面,并且没有刷新,它直接重定向到主页,主页被刷新。 请帮助我如何在从“编辑配置文件”页面

  • 在TS文件中 用户详细信息应为 在管理组件中 我的问题是,当单击时,我不会被重定向到页面,但当我从url栏导航到/userdails时,我会看到组件

  • 我正在用MVVM light制作一个WindowsUniversal10应用程序。 但是现在,如果我单击ShowWeatherPage上的项目,我会导航到ShowWeatherDetailPage以获取有关单击项目的更多详细信息。但是我不知道我怎么能做到这一点。你能帮我做这个吗? 下面你可以找到我的代码。我使用IocContainers,每个页面都有一个viewmodel,只有命令绑定。

  • 接口说明 根据用户登录之后生成的唯一token获取用户权限 如需调用,请访问 开发者文档 来查看详细的接口使用说明 该接口仅开放给已获取SDK的开发者 API地址 POST /api/power/1.0.0/get 是否需要登录 是 请求字段说明 参数 类型 请求类型 是否必须 说明 token string form 是 用户登录标识 响应字段说明 参数 类型 说明 data String 数据