- 

Available since OmniFaces 1.4

This ResourceHandler implementation allows the developer to map Faces resources on an URL pattern of /jakarta.faces.resource/* (basically, the value of ResourceHandler.RESOURCE_IDENTIFIER) without the need for an additional FacesServlet prefix or suffix URL pattern in the default produced resource URLs, such as /jakarta.faces.resource/faces/css/style.css or /jakarta.faces.resource/css/style.css.xhtml. This resource handler will produce unmapped URLs like /jakarta.faces.resource/css/style.css. This has the major advantage that the developer don't need the #{resource} EL expression anymore in order to properly reference relative URLs to images in CSS files.

So, given the following folder structure,

WebContent
 `-- resources
      `-- css
           |-- images
           |    `-- background.png
           `-- style.css

And the following CSS file reference (note: the library is not supported by the UnmappedResourceHandler! this is a technical limitation, just exclusively use name):

<h:outputStylesheet name="css/style.css" />

you can in css/style.css just use:

body {
    background: url("images/background.png");
}

instead of

body {
    background: url("#{resource['css/images/background.png']}");
}

This has in turn the advantage that you don't need to modify the background image or font face URLs in CSS files from 3rd party libraries such as Twitter Bootstrap, FontAwesome, etcetera.

Installation

To get it to run, this handler needs be registered as follows in faces-config.xml:

<application>
    <resource-handler>org.omnifaces.resourcehandler.UnmappedResourceHandler</resource-handler>
</application>

And the FacesServlet needs to have an additional mapping /jakarta.faces.resource/* in web.xml. You can just add it as a new <url-pattern> entry to the existing mapping of the FacesServlet. For example, assuming that you've already a mapping on *.xhtml:

<servlet-mapping>
    ...
    <url-pattern>*.xhtml</url-pattern>
    <url-pattern>/jakarta.faces.resource/*</url-pattern>
</servlet-mapping>

CombinedResourceHandler

If you're also using the CombinedResourceHandler or any other custom resource handler, then you need to ensure that this is in faces-config.xml declared before the UnmappedResourceHandler. Thus, like so:

<application>
    <resource-handler>org.omnifaces.resourcehandler.CombinedResourceHandler</resource-handler>
    <resource-handler>org.omnifaces.resourcehandler.UnmappedResourceHandler</resource-handler>
</application>

Otherwise the combined resource handler will still produce mapped URLs. In essence, the one which is later registered wraps the previously registered one.