好主意。 JSF API 不支持此功能,但理论上可以通过自定义脚本渲染器实现。我对此进行了一些尝试,这确实是可能的。只需创建一个MultiScriptRenderer
which extends ScriptRenderer
并覆盖encodeEnd() http://download.oracle.com/javaee/6/api/javax/faces/render/Renderer.html#encodeEnd%28javax.faces.context.FacesContext,%20javax.faces.component.UIComponent%29检查是否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
如下(Sorry, @FacesRenderer http://download.oracle.com/javaee/6/api/javax/faces/render/FacesRenderer.html在 JSF 2.2 中针对这个特定的极端情况修复注释之前,注释不会起作用,另请参阅JSF 问题 1748 http://java.net/jira/browse/JAVASERVERFACES-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 上运行良好。您可以使用类似的模式*.js
and prefix*.js
。特定的代码示例仅与特定的 JSF 实现紧密耦合,以节省代码样板。它还要求在部署时扩展 WAR,否则通过以下方式浏览目录File#listFiles()
不可能(因此排除某些(较旧的)servletcontainer 版本/配置)。对于其他 JSF 实现,您必须扩展其ScriptRenderer
相反,或者如果您想独立于实现,则编写一个全新的(这应该很简单,只需查看标准ScriptRenderer
来源(如果你卡住了)。