2013-08-09 9 views
10

PF 3.5.10, 2.1.21 Mojarra, omnifaces 1,5Jak używać JSF wersjonowanie zasobów w słoiku

Mam biblioteki JSF (z tylko pliki CSS). Ta biblioteka znajduje się w pliku .jar. Css zostanie włączony do xhtml z <h:outputStylesheet library="mylib" name="css/mycss.css">.

w HTML jest renderowane na następujące kwestie: plik localhost:8080/cms/javax.faces.resource/css/mycss.css.jsf?ln=mylib

CSS primefaces jest oddawana: localhost:8080/cms/javax.faces.resource/primefaces.js.jsf?ln=primefaces&v=3.5.10

Zawiadomienie wersję biblioteki (& 3.5.10) na końcu. Jak mogę zrobić to samo? Czy powinienem napisać wersję w Manifest.mf? Lub w jaki sposób mogę użyć wersji jsf w pliku jar?

+0

możliwy duplikat [Jak określić wersję biblioteki zasobów w JSF2?] (Http://stackoverflow.com/questions/9868068/how-to-specify-resource-library-version-in-jsf2) –

+0

Nie, I nie jest to duplikat, ponieważ pytanie dotyczy pliku JAR. W słoiku jest inaczej. Zobacz odpowiedź BalusC: [link] (http://stackoverflow.com/a/11988418/2023524) – Tony

Odpowiedz

17

To niestety nie jest możliwe. Wersja biblioteki nie jest obsługiwana dla zasobów w JAR.

Masz zasadniczo 2 opcje:

  1. Zrób to w prosty sposób i brzydki, to czas uruchamiania serwera jako ciąg kwerendy. Biorąc pod uwagę, że używasz OmniFaces, można użyć jej wbudowane #{startup} udało fasola odnosząc instancji java.util.Date w zakresie aplikacji:

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

    A może masz już wersję jako pewnego zmiennej aplikacji.

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

    Aktualizacja: po wszystkim, to nie działa dla <h:outputStylesheet>. Zobacz także https://java.net/jira/browse/JAVASERVERFACES-3941 i https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1395. To działa na <h:outputScript> chociaż, który miał bardzo simliar raport o błędzie, który został wdrożony wkrótce https://java.net/jira/browse/JAVASERVERFACES-1212

  2. Do the same as PrimeFaces, utworzyć niestandardowy 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; 
        } 
    
    } 
    

    A jeśli zdarzy się już używać OmniFaces, to można zrobić prościej:

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

    czy inaczej, aby go uruchomić, zarejestrować go jako <resource-handler> w /META-INF/faces-config.xml słoika.

    <application> 
        <resource-handler>com.example.MyVersionResourceHandler</resource-handler> 
    </application> 
    
+0

Dziękuję! Bardzo pomocna odpowiedź. Twój pomysł w 1 '# {startup}' jest miły. Więc css klienta będzie zawsze aktualizowany i nie można zapomnieć o zmianie wersji. Kolejne pytanie: czy jest możliwe umieszczenie tego ResourceHandler w pliku jar i użycie go tam? Więc każdy słoik będzie niezależny. – Tony

+2

Tak, umieść klasę w JAR i zarejestruj ją w pliku '/ META-INF/faces-config.xml' pliku JAR. Jest to również wspomniane w dolnej części odpowiedzi, w przypadku, gdy go przegapiłeś. – BalusC

+0

Dziękujemy! Jestem wielkim fanem twoich tutoriali. Bardzo pomagają. – Tony

3

Można również korzystać z wersji projektu i dołączyć go jako numer wersji dla plików zasobów. Można to zrobić za pomocą maven-war-plugin. maven-war-plugin będzie przeglądać twoje strony w czasie budowania i zastępować określone właściwości.

Poniższy przykład pokazuje, jak skonfigurować maven-war-plugin filtrowanie zasobów webapp w celu wstrzyknięcia właściwość niestandardową 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> 

Obiekt asset.version mogą być następnie wykorzystane w pliku JSF.

Oto przykład testowane z 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}" /> 

Wynik (w moim przypadku) będą następujące:

<script type="text/javascript" src="/context-path/javax.faces.resource/js/libs/pure/pure-min.css.xhtml?v=1.0.15-SNAPSHOT"></script> 
+1

Dobra uwaga! Dziękuję Ci. To ciekawe rozwiązanie, które wykorzystuje Mavena. Niestety tego nie robimy. – Tony

0

@Balusc odpowiedź powiedział: „dobrze, nie błąd, ale nadzór i błąd spec ". Wygląda na to, że zasoby css wdrożone w bibliotekach nie mogą być wersjonowane za pomocą mojarra 2.2.14. Czy to jest poprawne? Próbowałem zaimplementować twoje rozwiązanie za pomocą niestandardowego ResourceHandler, ale zasób zwracany przez getWrapped(). CreateResource (resourceName, libraryName) zawsze zwraca wartość null. Wygląda na to, że createResource() próbuje znaleźć zasoby biblioteki (takie jak css/layout.css) ze ścieżką/META-INF/resources /, ale brakuje jej wersji.

Aby obejść ten problem mam overrided metoda createResource na niestandardowym ResourceHandler która rozciąga Omnifaces DefaultResourceHandler dodać wersji prefiks do 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); 
} 

Z tego obejścia wygenerowany link wygląda

<link type="text/css" rel="stylesheet" href="/javax.faces.resource/1_0_3/css/layout.css?ln=common&amp;v=1_0_3"/> 

dla deklaracji OutputStyleet

<h:outputStylesheet library="common" name="css/layout.css" /> 

Nie jestem pewien, czy to najlepsze rozwiązanie.

Powiązane problemy