问题描述
我正在使用JSF 2.0,并且正在寻找一种方法来包含页面上给定文件夹中的所有javascript,即做类似的事情
I am using JSF 2.0, and am looking for a means to include all the javascripts from a given folder on a page, i.e. do something like
<h:outputScript library="javascript" name="*.js" target="head" />
这种事情甚至可能吗?我是否应该使用Java代码编写自定义组件来实现此目的?
Is this kind of thing even possible? Should I write a custom component using java code to achieve this?
感谢您的帮助,
塞巴斯蒂安·特朗普(SébastienTromp)
Thanks for your help,
Sébastien Tromp
推荐答案
好主意. JSF API不支持此功能,但是从理论上讲,使用自定义脚本渲染器是可能的.我在它周围玩了一些,这确实是可能的.只需创建一个MultiScriptRenderer
其中extends ScriptRenderer
并覆盖 encodeEnd()
来检查name
属性是否包含*
通配符,然后通过扫描匹配的文件来进行相应处理资源文件夹中的这种模式.
Nice idea. This is not supported by the JSF API, but it's in theory possible with a custom script renderer. I played somewhat around it and it's indeed possible. Just create a MultiScriptRenderer
which extends ScriptRenderer
and override encodeEnd()
to check if the name
attribute contains the *
wildcard and then handle accordingly by scanning for files matching this pattern in the resources folder.
这是一个开球示例:
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问题1748 ):
Register it in faces-config.xml
as follows (Sorry, @FacesRenderer
annotation isn't going to work until it's fixed in JSF 2.2 for this specific corner case, see also 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()
浏览目录(因此不包括某些(较旧的)servlet容器版本/配置).对于其他JSF实现,您必须扩展其ScriptRenderer
,或者如果您想要独立于实现,则编写一个全新的代码(尽管这应该非常简单,如果遇到困难,只需看一下标准ScriptRenderer
源代码).
Works fine on Mojarra 2.0.3 here. You can use patterns like *.js
and prefix*.js
. The particular code example is only tight coupled to a specific JSF implementation to save code boilerplate. It also requires that the WAR is expanded on deploy, otherwise browsing the directory by File#listFiles()
won't be possible (which thus excludes certain (older) servletcontainer versions/configurations). For other JSF implementations you'll have to extend its ScriptRenderer
instead, or write a whole new one if you want to be implementation independent (which should be pretty simple though, just look at standard ScriptRenderer
source if you stucks).
这篇关于是否可以在JSF中包含一个文件夹中的所有javascripts文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!