【问题标题】:Obtaining Facelets templates/files from an external filesystem or database从外部文件系统或数据库获取 Facelets 模板/文件
【发布时间】:2012-10-28 20:09:55
【问题描述】:

我能够成功地让它与我的应用程序中的模板一起使用:

<ui:decorate template="/WEB-INF/templates/mytemplate.xhtml">

我还可以将模板移动到JAR/META-INF/templates/mytemplate.xhtml 并让它工作:

<ui:decorate template="/templates/mytemplate.xhtml">

我实际上想把这个文件放到文件系统(或数据库)上。我怎样才能做到这一点?我发现了很多与com.sun.facelets.impl.DefaultResourceResolver 相关的东西,但我认为这实际上与覆盖模板的服务无关。它没有尝试解析 URL,它只是尝试以某种方式在类路径上获取文件。

【问题讨论】:

    标签: jsf jsf-2 resources external facelets


    【解决方案1】:

    如果您已经在使用 JSF 2.2,则可以通过提供自定义 ResourceHandler 来执行此操作,其中您在 createViewResource() 中返回所需的视图资源。

    public class FaceletsResourceHandler extends ResourceHandlerWrapper {
    
        private ResourceHandler wrapped;
    
        public FaceletsResourceHandler(ResourceHandler wrapped) {
            this.wrapped = wrapped;
        }
    
        @Override
        public ViewResource createViewResource(FacesContext context, final String name) {
            ViewResource resource = super.createViewResource(context, name);
    
            if (resource == null) {
                resource = new ViewResource() {
                    @Override
                    public URL getURL() {
                        try {
                            return new File("/some/base/path", name).toURI().toURL();
                        } catch (MalformedURLException e) {
                            throw new FacesException(e);
                        }
                    }
                };
            }
    
            return resource;
        }
    
        @Override
        public ResourceHandler getWrapped() {
            return wrapped;
        }
    
    }
    

    faces-config.xml注册如下:

    <application>
        <resource-handler>com.example.FaceletsResourceHandler</resource-handler>
    </application>
    

    或者,如果您还没有使用 JSF 2.2,那么请改用 ResourceResolver

    public class FaceletsResourceResolver extends ResourceResolver {
    
        private ResourceResolver parent;
    
        public FaceletsResourceResolver(ResourceResolver parent) {
            this.parent = parent;
        }
    
        @Override
        public URL resolveUrl(String path) {
            URL url = parent.resolveUrl(path); // Resolves from WAR.
    
            if (url == null) {
                try {
                    url = new File("/some/base/path", path).toURI().toURL();
                } catch (MalformedURLException e) {
                    throw new FacesException(e);
                }
    
            }
    
            return url;
        }
    
    }
    

    web.xml注册如下:

    <context-param>
        <param-name>javax.faces.FACELETS_RESOURCE_RESOLVER</param-name>
        <param-value>com.example.FaceletsResourceResolver</param-value>
    </context-param>
    

    无论如何,为了从数据库中提供资源,您可以将它们保存/缓存在(临时)磁盘文件系统上,这样您就可以通过File 提供URL,或者发明一个自定义协议,例如db://,并提供自定义URLStreamHandlerFactoryURLStreamHandler 实现来执行从数据库流式传输的实际工作。你可以在这里找到一个启动示例Registering and using a custom java.net.URL protocol

    【讨论】:

    • 嗨 BalusC..这有助于我开始。我似乎可以很好地获取实际的 .xhtml 页面。但它似乎不适用于使用模板。我编辑问题以显示我现在遇到的当前错误。
    • 该文件显然不存在。扩展启动示例以使用 File#exists() 测试并在不使用时返回 null
    • 我发现了问题...您的解决方案确实有效。但这取决于我如何定义模板。例如,如果我使用 template="myfile.xhtml" 它将失败。但是如果我做 template="/myfile.xhtml" 它将进入 ResourceResolver。
    猜你喜欢
    • 2013-03-19
    • 1970-01-01
    • 2014-05-10
    • 2013-11-03
    • 2012-09-27
    • 2017-06-08
    • 1970-01-01
    • 2019-07-15
    • 1970-01-01
    相关资源
    最近更新 更多