一尘不染

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

jar

PF 3.5.10,Mojarra 2.1.21,全脸 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?


阅读 158

收藏
2022-05-31

共1个答案

一尘不染

不幸的是,这是不可能的。JAR 中的资源不支持库版本控制。

你基本上有两个选择:

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

coffeescript <h:outputStylesheet ... name="some.css?#{startup.time}" /> <h:outputScript ... name="some.js?#{startup.time}" />

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

coffeescript <h:outputStylesheet ... name="some.css?v=#{app.version}" /> <h:outputScript ... name="some.js?v=#{app.version}" />

更新:尽管如此,这不适用于<h:outputStylesheet>. 另请参阅:https ://github.com/javaserverfaces/mojarra/issues/3945或https://github.com/javaee/javaserverfaces-spec/issues/1395

虽然它适用,<h:outputScript>但它有一个非常相似的错误报告,很快就实施了https://github.com/javaserverfaces/mojarra/issues/1216

  1. 和 PrimeFaces 一样,创建一个自定义ResourceHandler.

```typescript
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;
   }

}
```

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

```scala
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");
   }

}
```

无论哪种方式,要使其运行,请将其注册为<resource-handler>JAR /META-INF/faces-config.xml

xml <application> <resource-handler>com.example.MyVersionResourceHandler</resource-handler> </application>

2022-05-31