Как использовать управление версиями JSF для ресурсов в jar
ПФ 3.5.10, Мохарра 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
CSS файл простых лиц отображается в: localhost:8080/cms/javax.faces.resource/primefaces.js.jsf?ln=primefaces&v=3.5.10
Обратите внимание на версию библиотеки (&3.5.10) в конце. Как я могу сделать то же самое? Должен ли я написать версию в Manifest.mf. Или как я могу использовать JSF-версии в JAR-файл?
3 ответа
К сожалению, это невозможно. Управление версиями библиотеки не поддерживается для ресурсов в JAR.
У вас есть в основном 2 варианта:
Сделайте это простым и безобразным способом, включив время запуска сервера в виде строки запроса. Учитывая, что вы используете OmniFaces, вы можете использовать его встроенный
#{startup}
управляемый бин, ссылаясь на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Сделайте так же, как 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
из банки.<application> <resource-handler>com.example.MyVersionResourceHandler</resource-handler> </application>
Вы также можете использовать версию своего проекта и добавить ее в качестве номера версии для своих файлов ресурсов. Это можно сделать с помощью maven-war-plugin
, maven-war-plugin
будет просматривать ваши страницы во время сборки и заменять определенные свойства.
В следующем примере показано, как настроить maven-war-plugin
отфильтровать ресурсы вашего веб-приложения, чтобы добавить пользовательское свойство 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>
Ответ @Balusc сказал: "Ну, не ошибка, но провал и провал спецификации". Кажется, что ресурсы CSS, развернутые в библиотеках, не могут быть версионированы с помощью mojarra 2.2.14. Это правильно? Я пытался реализовать ваше решение с помощью пользовательского ResourceHandler, но ресурс, возвращаемый getWrapped(). CreateResource(resourceName, libraryName) всегда возвращает ноль. Кажется, что createResource() пытается найти ресурсы библиотеки (например, css/layout.css) с помощью пути /META-INF/resources/, но ему не хватает версии.
Чтобы обойти проблему, я переопределил метод createResource в пользовательском ResourceHandler, который расширяет 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" />
Я не уверен, что это лучший обходной путь.