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
注意最后的库版本(&amp; 3.5.10)。我怎么能做同样的事情?我应该在Manifest.mf中编写版本吗?或者如何在jar文件中使用jsf-versioning?
答案 0 :(得分:20)
遗憾的是,这是不可能的。 JAR中的资源不支持库版本控制。
你基本上有两种选择:
以简单而丑陋的方式执行此操作,将服务器的启动时间包括为查询字符串。鉴于您正在使用OmniFaces,您可以使用其内置#{startup}
托管bean引用应用程序范围中的java.util.Date
实例:
<h:outputStylesheet ... name="some.css?#{startup.time}" />
<h:outputScript ... name="some.js?#{startup.time}" />
或许您已将该版本作为某个应用程序变量。
<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
Do the same as 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;
}
}
或者,如果你碰巧已经使用过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的<resource-handler>
中将其注册为/META-INF/faces-config.xml
。
<application>
<resource-handler>com.example.MyVersionResourceHandler</resource-handler>
</application>
答案 1 :(得分:3)
您还可以使用项目版本并将其作为资源文件的版本号附加。这可以使用maven-war-plugin
完成。 maven-war-plugin
将在构建时查看您的页面并替换已定义的属性。
以下示例说明如何配置maven-war-plugin
以过滤您的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>
然后可以在您的JSF文件中使用asset.version
属性。
以下是使用JSF 2.2测试的示例:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html ...
xmlns:jsf="http://xmlns.jcp.org/jsf">
...
<script jsf:name="js/libs/pure/pure-min.css?v=${project.version}" />
结果(在我的情况下)将如下:
<script type="text/javascript" src="/context-path/javax.faces.resource/js/libs/pure/pure-min.css.xhtml?v=1.0.15-SNAPSHOT"></script>
答案 2 :(得分:0)
@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" />
我不确定这是最好的解决方法。