是否可以在JSF中包含一个文件夹中的所有javascripts文件?

时间:2010-12-19 10:07:20

标签: java javascript jsf jsf-2

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

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

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

感谢您的帮助,
SébastienTromp

2 个答案:

答案 0 :(得分:3)

我没有对此进行测试,但是如果不接受通配符,则可以通过支持bean中的java代码获取文件列表,并使用c:forEachui:repeat将其插入到头部中,如:< / p>

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

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

答案 1 :(得分:3)

好主意。 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来源,请编写一个全新的实现)你坚持了。)