如何拦截JSF视图解析以替换结果页面?

时间:2016-06-09 17:58:49

标签: jsf jsf-2 resources accessibility facelets

某个托管bean有一个返回"/private/myview.jsf"的操作方法。但是,而不更改此代码,我想执行一些检查并最终呈现视图"/private/other/myview.jsf"

因此,总而言之,我想在方法返回后将<{1}}转换为,将转换为之前实际视图呈现。< / p>

如何实现?

环境:

  1. Eclipse Luna
  2. Java 1.7
  3. JSF 2
  4. 当前状况

    Web应用程序完全可以运行但开发用于支持辅助功能。

    下一版本的要求

    要成为一个足够好的应用程序,供使用屏幕阅读器的盲人使用。

    详情

    经过一番研究,我们得出的结论是,我们现在必须拥有每个页面的可访问版本。

    我们将设计每个页面的可访问版本,问题是何时显示无法访问的版本以及何时显示可访问的版本。

    当用户点击页面顶部的某个链接时,我们决定应用程序将转为可访问模式(这不是默认状态)。在可访问模式下,仅呈现可访问的页面版本。

    我们不想审查所有应用程序,我们想要的是截取JSF的某些阶段并替换应该呈现的结果。例如,请考虑以下内容:

    1. 某个页面有一个链接或另一个页面的按钮,让我们说"/private/myview.jsf";
    2. 当处于可访问模式时,我们想告诉JSF不呈现"/private/other/myview.jsf",而应呈现"mysettings.xhtml""mysettings.xhtml";
    3. 这两个页​​面都将与相同的托管bean进行交互,并提供相同的功能,但是对于那些能够看到而另一个将被设计为对屏幕阅读器用户感到舒适的人来说,这将是一件好事。
    4. 提前致谢!

2 个答案:

答案 0 :(得分:2)

  

总而言之,我希望在方法返回后将"/private/myview.jsf"转换为"/private/other/myview.jsf",然后 实际视图渲染。

如果您已经使用JSF 2.2,则可以通过提供自定义ResourceHandeler来执行此操作,其中您可以根据某些条件在createViewResource()中返回所需的视图资源。

public class YourResourceHandler extends ResourceHandlerWrapper {

    private ResourceHandler wrapped;

    public YourResourceHandler(ResourceHandler wrapped) {
        this.wrapped = wrapped;
    }

    @Override
    public ViewResource createViewResource(FacesContext context, final String name) {
        if (someCondition) {
            name = name.replace("/private/", "/private/other/");
        }

        return super.createViewResource(context, name);
    }

    @Override
    public ResourceHandler getWrapped() {
        return wrapped;
    }

}

faces-config.xml注册的内容如下:

<application>
    <resource-handler>com.example.YourResourceHandler</resource-handler>
</application>

或者,如果您尚未使用JSF 2.2,请改用ResourceResolver

public class YourResourceResolver extends ResourceResolver {

    private ResourceResolver parent;

    public YourResourceResolver(ResourceResolver parent) {
        this.parent = parent;
    }

    @Override
    public URL resolveUrl(String path) {
        if (someCondition) {
            path = path.replace("/private/", "/private/other/");
        }

        return parent.resolveUrl(path);
    }

}

web.xml注册的内容如下:

<context-param>
    <param-name>javax.faces.FACELETS_RESOURCE_RESOLVER</param-name>
    <param-value>com.example.YourResourceResolver</param-value>
</context-param>

答案 1 :(得分:-1)

正如我所看到的,可能有两种可能的解决方案。

  1. 使用redirect()方法

    returnAction(){ ExternalContext context = FacesContext.getCurrentInstance().getExternalContext(); context.redirect("/private/other/myview.jsf"); //Relative path might vary based upon your business logic }

  2. 行动返回后的条件重定向;我们可以在faces-config.xml中维护导航规则,如下所示:

  3.     <navigation-rule>
            <navigation-case>
                <from-action>#{yourManagedBean.actionMethod}</from-action>
                <if>#{yourManagedBean.redirectAccessibleFlag}</if>   <!-- We maintain a boolean variable redirectAccessibleFlag in the managed Bean and set its value to true or false conditionally-->
                <to-view-id>/private/other/myview.jsf</to-view-id>
               <redirect/>
            </navigation-case>
        </navigation-rule>

    在第二种方法中,您可以在ApplicationScope中放置托管bean,以便在多个JSF页面中使用。

    虽然这些解决方案来自一般概念,但它们可能不一定属于“ 方法返回后 之前实际视图渲染。”但是你可以检查它是否能解决问题。