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