O que é a biblioteca de resources JSF e como ela deve ser usada?

Os componentes JSF , e têm um atributo de library . O que é isso e como isso deve ser usado? Há muitos exemplos na Web que o usam da seguinte maneira com o conteúdo / tipo de arquivo comum css , js e img (ou image ) como nome da biblioteca, dependendo da tag usada:

    

Como isso é útil? O valor da library nesses exemplos parece estar apenas repetindo o que já foi representado pelo nome da tag. Para um é baseado no nome da tag já óbvio que representa uma “biblioteca CSS”. Qual é a diferença com o seguinte, que também funciona da mesma maneira?

    

Além disso, a saída HTML gerada é um pouco diferente. Dado um caminho de contexto de /contextname e mapeamento FacesServlet em um padrão de URL de *.xhtml , o primeiro gera o seguinte HTML com o nome da biblioteca como parâmetro de solicitação:

    

Enquanto o último gera o seguinte HTML com o nome da biblioteca apenas no caminho do URI:

    

A última abordagem faz também, em retrospectiva, mais sentido do que a primeira abordagem. Como exatamente o atributo da library é útil?

Na verdade, todos esses exemplos na web em que o tipo de conteúdo / arquivo comum como “js”, “css”, “img”, etc, está sendo usado como nome da biblioteca são enganosos .

Exemplos do mundo real

Para começar, vamos ver como as implementações JSF existentes, como as bibliotecas de componentes Mojarra e MyFaces e JSF, como o PrimeFaces e o OmniFaces, o utilizam. Nenhum deles usa bibliotecas de resources dessa maneira. Eles o usam (sob os UIViewRoot#addComponentResource() , por UIViewRoot#addComponentResource() ou UIViewRoot#addComponentResource() ) da seguinte maneira:

         

Deve ficar claro que basicamente representa o nome comum da biblioteca / módulo / tema onde todos esses resources comumente pertencem.

Mais fácil identificação

Desta forma, é muito mais fácil especificar e distinguir de onde esses resources pertencem e / ou estão vindo. Imagine que você tenha um recurso primefaces.css em seu próprio aplicativo da web, no qual você está substituindo / ajustando alguns CSS padrão de PrimeFaces; se PrimeFaces não usasse um nome de biblioteca para seus próprios primefaces.css , então o próprio PrimeFaces não seria carregado, mas ao invés disso, o arquivo fornecido pela web, o qual quebraria o look’n’feel.

Além disso, quando você estiver usando um ResourceHandler personalizado, também poderá aplicar um controle mais refinado sobre os resources provenientes de uma biblioteca específica quando a library for usada da maneira correta. Se todas as bibliotecas de componentes tivessem usado “js” para todos os seus arquivos JS, como o ResourceHandler nunca distinguiria se é proveniente de uma biblioteca de componentes específica? Exemplos são OmniFaces CombinedResourceHandler e GraphicResourceHandler ; Verifique o método createResource() em que a biblioteca é verificada antes de delegar ao próximo manipulador de resources em cadeia. Desta forma, eles sabem quando criar CombinedResource ou GraphicResource para o efeito.

Notável deve ser que RichFaces fez errado. Ele não usou nenhuma library e criou uma outra camada de manipulação de resources e, portanto, é impossível identificar programaticamente os resources do RichFaces. Essa é exatamente a razão pela qual o OmniFaces CombinedResourceHander teve que introduzir um hack baseado em reflection para que ele funcionasse de qualquer maneira com os resources do RichFaces.

Sua própria aplicação web

Seu próprio webapp não precisa necessariamente de uma biblioteca de resources. É melhor simplesmente omitir isso.

    

Ou, se você realmente precisa ter um, basta dar um nome comum mais sensato, como “padrão” ou algum nome de empresa.

    

Ou, quando os resources são específicos de alguns gabaritos facelets mestre, você também pode fornecer o nome do gabarito, para facilitar a relação entre eles. Em outras palavras, é mais para fins de auto-documentário. Por exemplo, em um arquivo de modelo /WEB-INF/templates/layout.xhtml :

   

E um arquivo de modelo /WEB-INF/templates/admin.xhtml :

   

Para um exemplo do mundo real, verifique o código-fonte do OmniFaces .

Ou, quando você quiser compartilhar os mesmos resources em várias webapps e tiver criado um projeto “comum” para isso com base no mesmo exemplo que nesta resposta, que por sua vez é incorporado como JAR em webapp /WEB-INF/lib , em seguida, também referenciá-lo como biblioteca (o nome é gratuito à sua escolha; bibliotecas de componentes como OmniFaces e PrimeFaces também funcionam dessa maneira):

    

Versão de biblioteca

Outra vantagem principal é que você pode aplicar a versão da biblioteca de resources da maneira correta em resources fornecidos pelo seu próprio aplicativo da Web (isso não funciona para resources incorporados em um JAR). Você pode criar uma subpasta subordinada direta na pasta da biblioteca com um nome no padrão \d+(_\d+)* para indicar a versão da biblioteca de resources.

 WebContent |-- resources | `-- default | `-- 1_0 | |-- css | | `-- style.css | |-- img | | `-- logo.png | `-- js | `-- script.js : 

Ao usar essa marcação:

    

Isso gerará o seguinte HTML com a versão da biblioteca como parâmetro v :

    

Então, se você editou / atualizou algum recurso, então tudo que você precisa fazer é copiar ou renomear a pasta da versão para um novo valor. Se você tiver várias pastas de versão, o JSF ResourceHandler exibirá automaticamente o recurso a partir do número de versão mais alto, de acordo com as regras de ordenação numérica.

Então, ao copiar / renomear resources/default/1_0/* pasta para resources/default/1_1/* seguinte forma:

 WebContent |-- resources | `-- default | |-- 1_0 | | : | | | `-- 1_1 | |-- css | | `-- style.css | |-- img | | `-- logo.png | `-- js | `-- script.js : 

Em seguida, o último exemplo de marcação geraria o seguinte HTML:

    

Isso forçará o webbrowser a solicitar o recurso diretamente do servidor, em vez de mostrar aquele com o mesmo nome do cache, quando a URL com o parâmetro alterado for solicitada pela primeira vez. Dessa forma, os endusers não precisam fazer uma atualização (Ctrl + F5 e assim por diante) quando precisarem recuperar o recurso CSS / JS atualizado.

Observe que o versionamento de biblioteca não é possível para resources contidos em um arquivo JAR. Você precisaria de um ResourceHandler personalizado. Veja também Como usar o version control do JSF para resources no jar .

Veja também:

  • Versão de resources do JSF
  • Cache de resources estáticos do JSF2
  • Estrutura para vários projetos JSF com código compartilhado
  • Especificação do JSF 2.0 – Capítulo 2.6 Manipulação de Recursos