如何在 JSF 中加载动态资源?

Dan*_*lor 4 resources jsf

我想使用h:outputScript标签加载动态资源(生成的 JavaScript,技术上以 JSON 配置)作为动态资源。我知道我可以通过编写自己的 servlet 并通过普通标签脚本加载它来做到这一点,因为我更喜欢加载资源的“JSF 方式”。

有可能吗,怎么可能?

Bal*_*usC 6

是的,这是可能的。您可以通过使用特定的资源库名称并对其进行自定义ResourceHandler拦截并Resource在请求特定库的资源时返回自定义来实现此目的。

例如

<h:outputScript library="dynamicJs" name="some.js" />
Run Code Online (Sandbox Code Playgroud)

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);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

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.
    }

}
Run Code Online (Sandbox Code Playgroud)

要使其运行,请在 faces-config.xml 中按如下方式注册它:

<application>
    <resource-handler>com.example.DynamicJsResourceHandler</resource-handler>
</application>
Run Code Online (Sandbox Code Playgroud)

如果您碰巧使用 JSF 实用程序库OmniFaces,那么您还可以保存样板代码并从其扩展,org.omnifaces.resourcehandler.DynamicResource这样您只需要实现getInputStream(). 如果您不使用 OmniFaces,那么您始终可以使用其源代码作为指导。