使用JSF2包含上下文根之外的资源

3

我目前正在将一个应用程序从JSF 1.2和Richfaces 3.3升级到JSF 2和Richfaces 4。

使用JSF2的新的 h:outputStylesheet 组件时,我遇到了一些问题,无法使我的应用程序包含样式表。

这是我的旧代码:

<a4j:loadStyle src="resource:///com/testing/test/html/css/style.xcss" />

这是我新的代码(无法工作):


<h:outputStylesheet library="resource:///com/testing/test/html/css/" name="style.xcss" />

我尝试了各种变化但都没有成功。 在使用Firebug CSS标签时,我会收到一个“RES_NOT_FOUND”消息。

有什么想法吗?

谢谢

1个回答

5
<h:outputStylesheet library="resource:///com/testing/test/html/css/" name="style.xcss" />

由于一个原因,这个方法无法工作 - 库名称不是资源的位置,而是用于确定资源位置的。
JSF运行时服务资源的方式在JSF 2.0规范第2章"请求处理生命周期"中详细说明。资源处理是在JSF的常规执行和呈现生命周期之外进行的(用于服务视图请求)。在运行时,与应用程序相关联的ResourceHandler负责服务资源请求。
ResourceHandler使用基于路径的方法来查找请求。默认实现允许将资源放置在两个位置:
1. Web应用程序根目录下。标识符为/resources/<resourceIdentifier>的资源必须放置在Web应用程序根目录下的/resources目录中。
2. 类路径下。标识符为META-INF/resources/<resourceIdentifier>的资源必须存在于类路径下的目录中。在Web应用程序中,我注意到该目录应该是Web应用程序根目录/WEB-INF/classes/META-INF/resources目录或父类加载器中一个目录下的META-INF/resources目录,甚至可以在类路径中存在的JAR文件中。显然,JSF 2库/框架(如PrimeFaces)采取的是最后一种选项。
JSF规范还指定了<resourceIdentifier>可以由区域设置、库版本和资源版本以及资源名称本身组成。这在ResourceHandler API文档中简明地处理。

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.

基于上述内容,以下可能会起作用:
<h:outputStylesheet library="com/testing/test/html/css" name="style.xcss" />

只要样式表style.xcss存在于目录结构com/testing/test/html/css中,位于上述两个区域之一。根据您的需求,将其放置在上下文根之外的唯一可行选项是Web应用程序根/WEB-INF/classes/META-INF/resources或类路径中的任何其他适当目录/JAR(包含META-INF/resources目录)。当然,这是假设RichFaces没有提供自己的ResourceHandler实现;如果它确实提供了一个,则应查看如何扩展默认实现以允许在其他位置放置资源。
在Mojarra中,com.sun.faces.application.resource.ResourceHandlerImpl类扩展了ResourceHandler类。ResourceHanderImpl使用com.sun.faces.application.resource.ResourceManager类来查找资源。而ResourceManager则将资源加载委托给com.sun.faces.application.resource.WebappResourceHelpercom.sun.faces.application.resource.ClasspathResourceHelper类。顾名思义,前者负责在Web应用程序根目录中查找资源,而后者负责从类路径中加载资源。通过这些类,人们会发现无法加载库时会在服务器日志中记录失败的尝试;RES_NOT_FOUND值不是由这些类生成的,而是由负责生成页面输出的渲染器生成的。

谢谢你详细的回复,Vineet。我会研究你提出的建议,并很可能回来接受这个答案 :) - Thomas Buckley
我已经重新组织了应用程序,现在将css/js/images都存储在webapp的资源文件夹下,感谢Vineet。 - Thomas Buckley
2
注意:根据JSF规范,库名称中的斜杠(/)字符是非法的。 - ՕլՁՅԿ
@Péter Varga,我没有说库名称中允许使用斜杠;实际上,整个资源标识符都允许使用斜杠。 - Vineet Reynolds

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接