Как использовать JSF-версию для ресурсов в банке
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
Файл CSS-шрифтов отображается:
localhost:8080/cms/javax.faces.resource/primefaces.js.jsf?ln=primefaces&v=3.5.10
Обратите внимание на версию библиотеки (& 3.5.10) в конце. Как я могу сделать то же самое? Должен ли я писать версию в Manifest.mf. Или как я могу использовать jsf-версию в файле jar?
Ответы
Ответ 1
К сожалению, это невозможно. Библиотека версий не поддерживается для ресурсов в JAR.
У вас есть в основном 2 варианта:
-
Сделайте это простым и уродливым способом, включите время запуска сервера в качестве строки запроса. Учитывая, что вы используете 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://java.net/jira/browse/JAVASERVERFACES-3941 и https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1395. Он работает для <h:outputScript>
, хотя у него был очень простой отчет об ошибке, который был довольно скоро реализован https://java.net/jira/browse/JAVASERVERFACES-1212
-
Сделайте то же самое, что и 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");
}
}
В любом случае, чтобы запустить его, зарегистрируйте его как <resource-handler>
в /META-INF/faces-config.xml
JAR.
<application>
<resource-handler>com.example.MyVersionResourceHandler</resource-handler>
</application>
Ответ 2
Вы также можете использовать свою версию проекта и добавить ее в качестве номера версии для ваших файлов ресурсов. Это можно сделать, используя 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>
Свойство asset.version
затем может быть использовано в вашем файле JSF.
Вот пример, протестированный в 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>
Ответ 3
@Balusc ответ сказал: "Ну, а не ошибка, но надзор и spec не работают". Кажется, что ресурсы css, развернутые в библиотеках, не могут быть версией с mojarra 2.2.14. Это правильно? Я попытался реализовать ваше решение с помощью специального ResourceHandler, но ресурс, возвращаемый функцией getWrapped(). CreateResource (resourceName, libraryName) всегда возвращает null. Кажется, что createResource() пытается найти ресурсы библиотеки (например, css/layout.css) с помощью пути /META -INF/resources/, но ему не хватает версии.
Чтобы обойти проблему, я переопределил метод createResource на настраиваемом ResourceHandler, который расширяет Omnifaces DefaultResourceHandler, чтобы добавить префикс версии к ресурсуName
@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" />
Я не уверен, что это лучший способ обхода.