【问题标题】:How to load dynamic resources in JSF?如何在 JSF 中加载动态资源?
【发布时间】:2013-02-06 10:53:01
【问题描述】:

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

有可能吗,怎么做?

【问题讨论】:

    标签: jsf resources


    【解决方案1】:

    是的,这是可能的。您可以通过使用特定的资源库名称并对其进行自定义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 作为指导。

    【讨论】:

    • 是否可以注册多个资源处理程序,每个处理程序支持一个库,或者该功能必须合并到单个实现中?
    • 是的。 &lt;application&gt; 中可以有 0-* &lt;resource-handler&gt; 条目。它们按照它们在 XML 中出现的顺序进行初始化。
    • 好的,但是现在我通过实现我需要将Resource实现提供给DynamicJsResource,或者从ResourceImpl复制很长的代码...
    • 我需要实现诸如 getURL 和 getRequestPath 之类的方法,但我不知道该怎么做... PrimeFaces 通过重载方法 handleResourceRequest(FacesContext context) 以某种方式超越了它,但对我来说不是正常运行,但我收到错误“resourceName 消息引用的资源和 libraryName i18n 在调用 ResourceHandler.createResource 时找不到。它将被忽略。”
    • DynamicJsResource 类不能从您的示例中的 ResourceWrapper 扩展,因为实际上没有什么要包装的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-16
    • 2012-04-29
    相关资源
    最近更新 更多