Jsf 2 如何对jar中的资源使用JSF版本控制
PF 3.5.10、Mojarra 2.1.21、omnifaces 1.5 我有一个JSF库(只有css文件)。此库位于.jar文件中。css将包含在xhtml中Jsf 2 如何对jar中的资源使用JSF版本控制,jsf-2,jar,resources,versioning,Jsf 2,Jar,Resources,Versioning,PF 3.5.10、Mojarra 2.1.21、omnifaces 1.5 我有一个JSF库(只有css文件)。此库位于.jar文件中。css将包含在xhtml中 在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=
在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版本控制?不幸的是,这是不可能的。JAR中的资源不支持库版本控制 您基本上有两种选择:
{startup}
托管bean引用应用程序范围中的java.util.Date
实例:
<h:outputStylesheet ... name="some.css?#{startup.time}" />
<h:outputScript ... name="some.js?#{startup.time}" />
或者,如果您碰巧已经使用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");
}
}
无论哪种方式,要让它运行,请在JAR的/META-INF/faces config.xml
中注册为
<application>
<resource-handler>com.example.MyVersionResourceHandler</resource-handler>
</application>
com.example.MyVersionResourceHandler
您还可以使用项目版本,并将其附加为资源文件的版本号。这可以使用
maven-war插件来完成。maven-war插件将在构建期间查看您的页面,并替换已定义的属性
下面的示例演示如何配置maven-war插件
,以过滤您的webapp资源,从而注入自定义属性asset.version
:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" ...>
...
<properties>
<asset.version>${project.version}</asset.version>
</properties>
...
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>gif</nonFilteredFileExtension>
<nonFilteredFileExtension>ico</nonFilteredFileExtension>
<nonFilteredFileExtension>jpg</nonFilteredFileExtension>
<nonFilteredFileExtension>png</nonFilteredFileExtension>
<nonFilteredFileExtension>pdf</nonFilteredFileExtension>
</nonFilteredFileExtensions>
<failOnMissingWebXml>false</failOnMissingWebXml>
<webResources>
<webResource>
<directory>${basedir}/src/main/webapp</directory>
<filtering>true</filtering>
</webResource>
</webResources>
</configuration>
</plugin>
...
</plugins>
</build>
</project>
结果(就我而言)如下:
<script type="text/javascript" src="/context-path/javax.faces.resource/js/libs/pure/pure-min.css.xhtml?v=1.0.15-SNAPSHOT"></script>
@Balusc回应说“好吧,不是bug,而是疏忽和规范失败”。似乎部署在库中的css资源无法使用mojarra 2.2.14进行版本控制。是这样吗?我尝试使用自定义ResourceHandler实现您的解决方案,但getWrapped()返回的资源。createResource(resourceName,libraryName)始终返回null。createResource()似乎试图用path/META-INF/resources/查找库的资源(如css/layout.css),但它缺少版本
为了解决这个问题,我在自定义ResourceHandler上重写了createResource方法,该方法扩展了Omnifaces DefaultResourceHandler,以向resourceName添加版本前缀
@Override
public Resource createResource(String resourceName, String libraryName) {
if (libraryName != null && libraryName.equals(LIBRARY_NAME)) {
if (!resourceName.startsWith(version)) {
resourceName = version + "/"+resourceName;
}
}
return super.createResource(resourceName, libraryName);
}
通过此解决方案,生成的链接如下所示
<link type="text/css" rel="stylesheet" href="/javax.faces.resource/1_0_3/css/layout.css?ln=common&v=1_0_3"/>
对于outputStylesheet声明
<h:outputStylesheet library="common" name="css/layout.css" />
我不确定这是否是最好的解决方法。可能重复的否,我认为这不是重复,因为问题是关于jar文件的。在罐子里,这是不同的。见巴卢斯回答:谢谢!非常有用的回答。你在1{startup}
中的想法很好。因此,客户端css将始终更新,您不能忘记更改版本。另一个问题:是否可以将这个ResourceHandler放在jar文件中并从那里使用它?所以每个jar都是独立的。是的,将类放入jar中,并将其注册到jar的/META-INF/faces config.xml
。答案的底部也提到了这一点,因为你错过了它。和往常一样,回答得很好。但是,我发现com.sun.faces.application.resource.ResourceImpl将对具有版本信息的库使用v参数。所以我对这个伟大的例子做了一个小小的改变,改变了参数名。我正在使用优秀的生成一个git提交哈希,参数名为gch。@raupach:这是一个技术限制。几年后,如果你碰巧已经使用了OmniFaces,那么现在你再来看看如何用更少的代码来实现它:@marcel:好吧,不是bug,但是疏忽和规范失败了。看到了,很好!非常感谢。使用Maven是一个有趣的解决方案。不幸的是,我们没有这样做。
@Override
public Resource createResource(String resourceName, String libraryName) {
if (libraryName != null && libraryName.equals(LIBRARY_NAME)) {
if (!resourceName.startsWith(version)) {
resourceName = version + "/"+resourceName;
}
}
return super.createResource(resourceName, libraryName);
}
<link type="text/css" rel="stylesheet" href="/javax.faces.resource/1_0_3/css/layout.css?ln=common&v=1_0_3"/>
<h:outputStylesheet library="common" name="css/layout.css" />