【发布时间】:2013-02-06 10:53:01
【问题描述】:
我想使用h:outputScript 标签将动态资源(生成的JavaScript,技术上以JSON 配置)加载为动态资源。我知道我可以通过编写自己的 servlet 并通过普通标记脚本加载它来做到这一点,因为我更喜欢加载资源的“JSF 方式”。
有可能吗,怎么做?
【问题讨论】:
我想使用h:outputScript 标签将动态资源(生成的JavaScript,技术上以JSON 配置)加载为动态资源。我知道我可以通过编写自己的 servlet 并通过普通标记脚本加载它来做到这一点,因为我更喜欢加载资源的“JSF 方式”。
有可能吗,怎么做?
【问题讨论】:
是的,这是可能的。您可以通过使用特定的资源库名称并对其进行自定义ResourceHandler 拦截并在请求特定库的资源时返回自定义Resource 来实现此目的。
例如
<h:outputScript library="dynamicJs" name="some.js" />
与
public class DynamicJsResourceHandler extends ResourceHandlerWrapper {
public DynamicJsResourceHandler(ResourceHandler wrapped) {
super(wrapped);
}
@Override
public Resource createResource(String resourceName, String libraryName) {
if ("dynamicJs".equals(libraryName)) {
return new DynamicJsResource(resourceName);
} else {
return super.createResource(resourceName, libraryName);
}
}
}
和
public class DynamicJsResource extends Resource {
private String resourceName;
public DynamicJsResource(String resourceName) {
this.resourceName;
}
@Override
public String getRequestPath() {
// TODO: return "/context/javax.faces.resource/" + resourceName + ".xhtml?ln=dynamicJs";
}
@Override
public URL getURL() {
// TODO: return new URL("http://localhost:8080" + getRequestPath());
}
@Override
public Map<String, String> getResponseHeaders() {
// TODO: return desired HTTP response headers.
}
@Override
public InputStream getInputStream() throws IOException {
// TODO: return InputStream by resourceName.
}
@Override
public boolean userAgentNeedsUpdate(FacesContext context) {
// TODO: return true when resource has been modified in server side.
}
}
要让它运行,在 faces-config.xml 中注册如下:
<application>
<resource-handler>com.example.DynamicJsResourceHandler</resource-handler>
</application>
如果您碰巧使用 JSF 实用程序库 OmniFaces,那么您也可以保存样板代码并从其 org.omnifaces.resourcehandler.DynamicResource 扩展,这样您只需要实现 getInputStream()。如果您不使用 OmniFaces,那么您始终可以使用它的source code 作为指导。
【讨论】:
<application> 中可以有 0-* <resource-handler> 条目。它们按照它们在 XML 中出现的顺序进行初始化。