【问题标题】:Is it possible to include all javascripts files from one folder in JSF?是否可以在 JSF 中包含一个文件夹中的所有 javascripts 文件?
【发布时间】:2011-05-27 19:34:27
【问题描述】:

我正在使用 JSF 2.0,并且正在寻找一种方法来包含页面上给定文件夹中的所有 javascript,即执行类似的操作

<h:outputScript library="javascript" name="*.js" target="head" />

这种事情有可能吗?我应该使用 java 代码编写自定义组件来实现这一点吗?

感谢您的帮助,
塞巴斯蒂安·特罗姆普

【问题讨论】:

  • 我没有答案,但这确实是一个有趣的问题。如果使用标准工具无法做到这一点,那么它将对 JSF 2.1 提出很好的功能要求。

标签: java javascript jsf jsf-2


【解决方案1】:

好主意。 JSF API 不支持这一点,但理论上可以通过自定义脚本渲染器实现。我在它周围玩了一些,这确实是可能的。只需创建一个MultiScriptRenderer 其中extends ScriptRenderer 并覆盖encodeEnd() 以检查name 属性是否包含* 通配符,然后通过扫描资源文件夹中与此模式匹配的文件进行相应处理。

这是一个启动示例:

package com.example;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.Map;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import com.sun.faces.renderkit.html_basic.ScriptRenderer;

public class MultiScriptRenderer extends ScriptRenderer {

    @Override
    public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
        Map<String, Object> attributes = component.getAttributes();
        String name = (String) attributes.get("name");
        if (name.contains("*")) {
            String pattern = name.replace(".", "\\.").replace("*", ".*");
            String library = (String) attributes.get("library");
            File root = new File(context.getExternalContext().getRealPath("/resources/" + (library != null ? library : "")));
            for (File file : root.listFiles()) {
                if (file.getName().matches(pattern)) {
                    attributes.put("name", file.getName());
                    super.encodeEnd(context, component);
                }
            }
            attributes.put("name", name); // Put original name back. You never know.
        } else {
            super.encodeEnd(context, component);
        }
    }
}

按如下方式在faces-config.xml 中注册它(抱歉,@FacesRenderer 注释在 JSF 2.2 中针对这个特定的极端情况修复之前不会起作用,另请参阅JSF issue 1748

<render-kit>
    <renderer>
        <component-family>javax.faces.Output</component-family>
        <renderer-type>javax.faces.resource.Script</renderer-type>
        <renderer-class>com.example.MultiScriptRenderer</renderer-class>
    </renderer>
</render-kit>

在这里的 Mojarra 2.0.3 上运行良好。您可以使用*.jsprefix*.js 等模式。特定的代码示例仅与特定的 JSF 实现紧密耦合以节省代码样板。它还要求在部署时扩展 WAR,否则将无法通过 File#listFiles() 浏览目录(因此不包括某些(较旧的)servletcontainer 版本/配置)。对于其他 JSF 实现,您必须改为扩展其 ScriptRenderer,或者如果您想独立于实现,则编写一个全新的(这应该很简单,如果您遇到困难,只需查看标准的 ScriptRenderer 源代码)。

【讨论】:

  • 谢谢。与此同时,我发现了一些可以解决需要包含几个 javascript 文件的方法,但我肯定会把它放在手边以备后用。
  • 您(自动)将所有松散的 JS 文件压缩/缩小为单个 JS 文件?这确实也经常用于节省 HTTP 请求的数量。
  • 在此处参考 OmniFaces 解决方案
【解决方案2】:

我没有对此进行测试,但如果不接受通配符,您可以通过支持 bean 中的 java 代码获取文件列表,然后使用 c:forEachui:repeat 将它们插入头部,例如:

<ui:repeat value="#{bean.files}" var="file">
    <h:outputScript library="javascript" name="#{file}" target="head" />
</ui:repeat>

请注意,您不能提供h:outputScript 的绝对路径,但必须从中提取前缀(JSF 资源路径之前的部分)。

【讨论】:

    猜你喜欢
    • 2013-11-22
    • 2013-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-05
    • 2010-09-13
    • 2016-08-02
    • 2012-06-03
    相关资源
    最近更新 更多