问题
I'm currently upgrading an application from JSF 1.2 and Richfaces 3.3 to JSF 2 and Richfaces 4.
I'm having issues getting my application to include stylesheets using JSF2's new h:outputStylesheet component
Here is my old code:
<a4j:loadStyle src="resource:///com/testing/test/html/css/style.xcss" />
And here is what I have for my new code (Not working):
<h:outputStylesheet library="resource:///com/testing/test/html/css/" name="style.xcss" />
I've tried various variations but none have worked. I get a message saying RES_NOT_FOUND when using firebugs css tab.
Any ideas?
Thanks
回答1:
<h:outputStylesheet library="resource:///com/testing/test/html/css/" name="style.xcss" />
will not work for one reason - the library name is not the location of the resource, rather it is used to determine the location of the resource.
The manner in which the JSF runtime serves resources is detailed in the JSF 2.0 specification in chapter 2 titled "Request Processing Lifecyle". Resource handling is performed outside the confines of the usual Execute and Render lifecyle of JSF (that is used to service View requests). At runtime, a ResourceHandler
associated with the Application
is responsible for serving Resource requests.
The ResourceHandler
uses a path based approach for looking up requests. The default implementation allows for resources to be placed in two locations:
- In the Web-Application Root. Resources with identifier have to be placed in the
/resources
directory under the Web Application root, as/resources/<resourceIdentifier>
. - In the Classpath. Resources with identifier must be present in the Classpath under the
META-INF/resources
directory, again asMETA-INF/resources/<resourceIdentifier>
. In a web application, I've noticed that the directory should be theWeb Application Root/WEB-INF/classes/META-INF/resources
directory or aMETA-INF/resources
directory under one of the directories in the parent classloader(s), or even in a JAR present in the Classpath. Apparently, the last option is the one undertaken by JSF 2 libraries/frameworks like PrimeFaces.
The JSF specification also specifies how the <resourceIdentifier>
may consist of locales, library versions and resource versions, apart from the resource name itself. This is dealt with in a concise manner, in the ResourceHandler API documentation:
Packaging Resources
ResourceHandler defines a path based packaging convention for resources. The default implementation of ResourceHandler must support packaging resources in the classpath or in the web application root. See section JSF.2.6.1 of the spec prose document linked in the overview summary for the normative specification of packaging resources.
Briefly, The default implementation must support packaging resources in the web application root under the path
resources/<resourceIdentifier>
relative to the web app root.
For the default implementation, resources packaged in the classpath must reside under the JAR entry name
META-INF/resources/<resourceIdentifier>
consists of several segments, specified as follows.
[localePrefix/][libraryName/][libraryVersion/]resourceName[/resourceVersion]
None of the segments in the resourceIdentifier may be relative paths, such as ‘../otherLibraryName’. The implementation is not required to support the libraryVersion and resourceVersion segments for the JAR packaging case.
Note that resourceName is the only required segment.
Going by the above, the following may work:
<h:outputStylesheet library="com/testing/test/html/css" name="style.xcss" />
provided that the stylesheet style.xcss
is present in the directory structure com/testing/test/html/css
located in either of the two areas mentioned above. Going by your need to place it outside the context root, the only possible option would be Web Application Root/WEB-INF/classes/META-INF/resources
or any of the other suitable directory/JAR in the classpath (containing a META-INF/resources
directory. This is of course, assuming that RichFaces does not provide it's own implementation of a ResourceHandler
; if it does provide one, you should be looking at how it extends the default implementation to allow for resources to be placed elsewhere.
In Mojarra, the com.sun.faces.application.resource.ResourceHandlerImpl
class extends the ResourceHandler
class. ResourceHanderImpl
uses the com.sun.faces.application.resource.ResourceManager
class for finding resources. In turn, the ResourceManager
delegates the loading of resources to the com.sun.faces.application.resource.WebappResourceHelper
and com.sun.faces.application.resource.ClasspathResourceHelper
classes. As their names imply, the former is responsible for looking up resources in the Web Application root, while the former is responsible for loading resources from the classpath. Going through these classes, one would find that failed attempts to load libraries get logged in the server's log; the RES_NOT_FOUND
value is not generated by these classes, rather it is due to the renderer responsible for generating the page output.
来源:https://stackoverflow.com/questions/6846284/including-resources-outside-context-root-with-jsf2