7

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

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

我还可以将模板移动到/META-INF/templates/mytemplate.xhtmlJAR使其正常工作:

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

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

4

1 回答 1

13

如果您已经在 J​​SF 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>

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

于 2012-11-08T19:55:32.447 回答