work style resource res_not_found incluir from doesn and jsf jsf-2 resources

style - ¿Para qué sirve la biblioteca de recursos JSF y cómo debe usarse?



res_not_found (1)

Los <h:outputStylesheet> JSF <h:outputStylesheet> , <h:outputScript> y <h:graphicImage> tienen un atributo de library . ¿Qué es esto y cómo debe usarse? Hay muchos ejemplos en la web que lo usan de la siguiente manera con el contenido / tipo de archivo común css , js e img (o image ) como nombre de biblioteca, dependiendo de la etiqueta utilizada:

<h:outputStylesheet library="css" name="style.css" /> <h:outputScript library="js" name="script.js" /> <h:graphicImage library="img" name="logo.png" />

¿Cómo es útil? El valor de la library en esos ejemplos parece estar repitiendo lo que ya está representado por el nombre de la etiqueta. Para una <h:outputStylesheet> se basa en el nombre de la etiqueta, que ya es evidente que representa una "biblioteca CSS". ¿Cuál es la diferencia con lo siguiente que también funciona de la misma manera?

<h:outputStylesheet name="css/style.css" /> <h:outputScript name="js/script.js" /> <h:graphicImage name="img/logo.png" />

Además, la salida HTML generada es un poco diferente. Dada una ruta de contexto de /contextname y el mapeo de FacesServlet en un patrón de URL de *.xhtml , el primero genera el siguiente HTML con el nombre de la biblioteca como parámetro de solicitud:

<link rel="stylesheet" type="text/css" href="/contextname/javax.faces.resource/style.css.xhtml?ln=css" /> <script type="text/javascript" src="/contextname/javax.faces.resource/script.js.xhtml?ln=js"></script> <img src="/contextname/javax.faces.resource/logo.png.xhtml?ln=img" alt="" />

Mientras que este último genera el siguiente HTML con el nombre de la biblioteca solo en la ruta del URI:

<link rel="stylesheet" type="text/css" href="/contextname/javax.faces.resource/css/style.css.xhtml" /> <script type="text/javascript" src="/contextname/javax.faces.resource/js/script.js.xhtml"></script> <img src="/contextname/javax.faces.resource/img/logo.png.xhtml" alt="" />

El último enfoque hace en retrospectiva también más sentido que el enfoque anterior. ¿Qué tan exactamente es útil el atributo de library ?


En realidad, todos esos ejemplos en la web en los que el contenido / tipo de archivo común como "js", "css", "img", etc. se utilizan como nombre de biblioteca son confusos .

Ejemplos del mundo real

Para empezar, veamos cómo las implementaciones JSF existentes como Mojarra y MyFaces y las bibliotecas de componentes JSF como PrimeFaces y OmniFaces lo utilizan. Ninguno de ellos usa las bibliotecas de recursos de esta manera. Lo usan (debajo de las portadas, por @ResourceDependency o UIViewRoot#addComponentResource() ) de la siguiente manera:

<h:outputScript library="javax.faces" name="jsf.js" /> <h:outputScript library="primefaces" name="jquery/jquery.js" /> <h:outputScript library="omnifaces" name="omnifaces.js" /> <h:outputScript library="omnifaces" name="fixviewstate.js" /> <h:outputScript library="omnifaces.combined" name="[dynamicname].js" /> <h:outputStylesheet library="primefaces" name="primefaces.css" /> <h:outputStylesheet library="primefaces-aristo" name="theme.css" /> <h:outputStylesheet library="primefaces-vader" name="theme.css" />

Debe quedar claro que básicamente representa el nombre de la biblioteca / módulo / tema común al que todos esos recursos pertenecen comúnmente.

Identificación más fácil

De esta manera es mucho más fácil especificar y distinguir de dónde provienen y / o provienen esos recursos. Imagine que tiene un recurso primefaces.css en su propia aplicación web en la que está reemplazando / ajustando algunos CSS predeterminados de PrimeFaces; Si PrimeFaces no usara un nombre de biblioteca para sus propios primefaces.css , entonces el propio PrimeFaces no se cargaría, sino el nombre de la aplicación web, lo que rompería la sensación.

Además, cuando usa un ResourceHandler personalizado, también puede aplicar un control más preciso sobre los recursos que provienen de una biblioteca específica cuando la library se utiliza de la manera correcta. Si todas las bibliotecas de componentes hubieran usado "js" para todos sus archivos JS, ¿cómo distinguiría ResourceHandler si proviene de una biblioteca de componentes específica? Los ejemplos son OmniFaces CombinedResourceHandler y GraphicResourceHandler ; verifique el método createResource() en el que se verifica la biblioteca antes de delegar al siguiente manejador de recursos en cadena. De esta manera, saben cuándo crear CombinedResource o GraphicResource para ese propósito.

Notado debe ser que RichFaces lo hizo mal. No usó ninguna library y creó otra capa de manejo de recursos sobre ella y, por lo tanto, es imposible identificar los recursos de RichFaces mediante programación. Esa es exactamente la razón por la que OmniFaces CombinedResourceHander tuvo que introducir un hack basado en la reflexión para que funcione de todos modos con los recursos de RichFaces.

Tu propia aplicación web

Su propia aplicación web no necesita necesariamente una biblioteca de recursos. Será mejor que lo omitas.

<h:outputStylesheet name="css/style.css" /> <h:outputScript name="js/script.js" /> <h:graphicImage name="img/logo.png" />

O, si realmente necesita tener uno, puede darle un nombre común más sensible, como "predeterminado" o algún nombre de compañía.

<h:outputStylesheet library="default" name="css/style.css" /> <h:outputScript library="default" name="js/script.js" /> <h:graphicImage library="default" name="img/logo.png" />

O bien, cuando los recursos son específicos de alguna plantilla de Facelets maestra, también puede darle el nombre de la plantilla, para que sea más fácil relacionarse entre sí. En otras palabras, es más para fines autodocumentados. Por ejemplo, en un archivo de plantilla /WEB-INF/templates/layout.xhtml :

<h:outputStylesheet library="layout" name="css/style.css" /> <h:outputScript library="layout" name="js/script.js" />

Y un archivo de plantilla /WEB-INF/templates/admin.xhtml :

<h:outputStylesheet library="admin" name="css/style.css" /> <h:outputScript library="admin" name="js/script.js" />

Para ver un ejemplo del mundo real, verifique el código fuente de la vitrina OmniFaces .

O, cuando desee compartir los mismos recursos en varias aplicaciones web y haya creado un proyecto "común" para eso, basándose en el mismo ejemplo que en esta respuesta, que a su vez está incrustado como JAR en la aplicación web /WEB-INF/lib . luego, cámbielo también como biblioteca (el nombre es gratuito para su elección; las bibliotecas de componentes como OmniFaces y PrimeFaces también funcionan de esa manera):

<h:outputStylesheet library="common" name="css/style.css" /> <h:outputScript library="common" name="js/script.js" /> <h:graphicImage library="common" name="img/logo.png" />

Versiones de biblioteca

Otra ventaja principal es que puede aplicar las versiones de la biblioteca de recursos de la manera correcta en los recursos proporcionados por su propia aplicación web (esto no funciona para los recursos incrustados en un JAR). Puede crear una subcarpeta secundaria directa en la carpeta de la biblioteca con un nombre en el patrón /d+(_/d+)* para indicar la versión de la biblioteca de recursos.

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

Al utilizar este marcado:

<h:outputStylesheet library="default" name="css/style.css" /> <h:outputScript library="default" name="js/script.js" /> <h:graphicImage library="default" name="img/logo.png" />

Esto generará el siguiente HTML con la versión de la biblioteca como parámetro v :

<link rel="stylesheet" type="text/css" href="/contextname/javax.faces.resource/css/style.css.xhtml?ln=default&amp;v=1_0" /> <script type="text/javascript" src="/contextname/javax.faces.resource/js/script.js.xhtml?ln=default&amp;v=1_0"></script> <img src="/contextname/javax.faces.resource/img/logo.png.xhtml?ln=default&amp;v=1_0" alt="" />

Por lo tanto, si ha editado / actualizado algún recurso, todo lo que necesita hacer es copiar o cambiar el nombre de la carpeta de la versión a un nuevo valor. Si tiene varias carpetas de versión, el JSF ResourceHandler servirá automáticamente el recurso desde el número de versión más alto, de acuerdo con las reglas de ordenamiento numérico.

Por lo tanto, al copiar / renombrar resources/default/1_0/* carpeta en resources/default/1_1/* como sigue:

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

Entonces el último ejemplo de marcado generaría el siguiente HTML:

<link rel="stylesheet" type="text/css" href="/contextname/javax.faces.resource/css/style.css.xhtml?ln=default&amp;v=1_1" /> <script type="text/javascript" src="/contextname/javax.faces.resource/js/script.js.xhtml?ln=default&amp;v=1_1"></script> <img src="/contextname/javax.faces.resource/img/logo.png.xhtml?ln=default&amp;v=1_1" alt="" />

Esto obligará al navegador web a solicitar el recurso directamente desde el servidor en lugar de mostrar el que tiene el mismo nombre desde la memoria caché, cuando se solicita por primera vez la URL con el parámetro cambiado. De esta manera, no es necesario que los usuarios finales realicen una actualización (Ctrl + F5, etc.) cuando necesiten recuperar el recurso CSS / JS actualizado.

Tenga en cuenta que la versión de la biblioteca no es posible para los recursos incluidos en un archivo JAR. Necesitarías un ResourceHandler personalizado. Vea también Cómo usar el control de versiones JSF para los recursos en el tarro .

Ver también: