如何在jar中使用JSF版本控制资源

Ton*_*ony 12 versioning resources jar jsf-2

PF 3.5.10,Mojarra 2.1.21,omnifaces 1.5

我有一个JSF库(仅限css文件).该库位于.jar文件中.css将包含在xhtml中 <h:outputStylesheet library="mylib" name="css/mycss.css">.

在html中,它呈现如下: localhost:8080/cms/javax.faces.resource/css/mycss.css.jsf?ln=mylib

primefaces的CSS文件呈现为: localhost:8080/cms/javax.faces.resource/primefaces.js.jsf?ln=primefaces&v=3.5.10

注意最后的库版本(&3.5.10).我怎么能做同样的事情?我应该在Manifest.mf中编写版本吗?或者如何在jar文件中使用jsf-versioning?

Bal*_*usC 21

遗憾的是,这是不可能的.JAR中的资源不支持库版本控制.

你基本上有两个选择:

  1. 这是简单而丑陋的方式,包括服务器的启动时间作为查询字符串.鉴于您正在使用OmniFaces,您可以使用其内置#{startup}托管bean引用java.util.Date应用程序范围中的实例:

    <h:outputStylesheet ... name="some.css?#{startup.time}" />
    <h:outputScript ... name="some.js?#{startup.time}" />
    
    Run Code Online (Sandbox Code Playgroud)

    或者您可能已将该版本作为某个应用程序变量.

    <h:outputStylesheet ... name="some.css?v=#{app.version}" />
    <h:outputScript ... name="some.js?v=#{app.version}" />
    
    Run Code Online (Sandbox Code Playgroud)

    更新:尽管如此,这不起作用<h:outputStylesheet>.另见:https://github.com/javaserverfaces/mojarra/issues/3945https://github.com/javaee/javaserverfaces-spec/issues/1395

    <h:outputScript>虽然有效,但有一个非常简单的错误报告很快就实现了https://github.com/javaserverfaces/mojarra/issues/1216

  2. 与PrimeFaces一样,创建自定义ResourceHandler.

    public class MyVersionResourceHandler extends ResourceHandlerWrapper {
    
        private ResourceHandler wrapped;
    
        public MyVersionResourceHandler(ResourceHandler wrapped) {
            this.wrapped = wrapped;
        }
    
        @Override
        public Resource createResource(String resourceName) {
            return createResource(resourceName, null, null);
        }
    
        @Override
        public Resource createResource(String resourceName, String libraryName) {
            return createResource(resourceName, libraryName, null);
        }
    
        @Override
        public Resource createResource(String resourceName, String libraryName, String contentType) {
            final Resource resource = super.createResource(resourceName, libraryName, contentType);
    
            if (resource == null) {
                return null;
            }
    
            return new ResourceWrapper() {
    
                @Override
                public String getRequestPath() {
                    return super.getRequestPath() + "&v=1.0";
                }
    
                @Override // Necessary because this is missing in ResourceWrapper (will be fixed in JSF 2.2).
                public String getResourceName() {
                    return resource.getResourceName();
                }
    
                @Override // Necessary because this is missing in ResourceWrapper (will be fixed in JSF 2.2).
                public String getLibraryName() {
                    return resource.getLibraryName();
                }
    
                @Override // Necessary because this is missing in ResourceWrapper (will be fixed in JSF 2.2).
                public String getContentType() {
                    return resource.getContentType();
                }
    
                @Override
                public Resource getWrapped() {
                    return resource;
                }
            };
        }
    
        @Override
        public ResourceHandler getWrapped() {
            return wrapped;
        }
    
    }
    
    Run Code Online (Sandbox Code Playgroud)

    或者,如果您碰巧已经使用过OmniFaces,可以更简单地完成:

    public class YourVersionResourceHandler extends DefaultResourceHandler {
    
        public YourVersionResourceHandler(ResourceHandler wrapped) {
            super(wrapped);
        }
    
        @Override
        public Resource decorateResource(Resource resource) {
            if (resource == null || !"mylib".equals(resource.getLibraryName())) {
                return resource;
            }
    
            return new RemappedResource(resource, resource.getRequestPath() + "&v=1.0");
        }
    
    }
    
    Run Code Online (Sandbox Code Playgroud)

    无论哪种方式,让它运行,它注册为<resource-handler>/META-INF/faces-config.xml该JAR的.

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

  • 是的,将类放在JAR中并将其注册到JAR的`/ META-INF/faces-config.xml`中.在答案的底部也提到了这一点,因为你错过了它. (2认同)