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

Tho*_*ley 3 richfaces jsf-2

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

我在使用 JSF2 的新h:outputStylesheet组件让我的应用程序包含样式表时遇到问题

这是我的旧代码:

<a4j:loadStyle src="resource:///com/testing/test/html/css/style.xcss" />
Run Code Online (Sandbox Code Playgroud)


这是我的新代码(不起作用):

<h:outputStylesheet library="resource:///com/testing/test/html/css/" name="style.xcss" />
Run Code Online (Sandbox Code Playgroud)


我尝试过各种变体,但没有一个有效。使用 firebugs css 选项卡时,我收到一条消息,提示 RES_NOT_FOUND。

有任何想法吗?

谢谢

Vin*_*lds 5

<h:outputStylesheet library="resource:///com/testing/test/html/css/" name="style.xcss" />\n
Run Code Online (Sandbox Code Playgroud)\n\n

由于一个原因而不起作用 - 库名称不是资源的位置,而是用于确定资源的位置。

\n\n

JSF 运行时提供资源的方式在 JSF 2.0 规范的第 2 章“请求处理生命周期”中详细介绍。资源处理是在 JSF 的常规执行和渲染生命周期(用于服务视图请求)的范围之外执行的。在运行时,ResourceHandler与 关联的Application负责服务资源请求。

\n\n

ResourceHandler使用基于路径的方法来查找请求。默认实现允许将资源放置在两个位置:

\n\n
    \n
  • 在 Web 应用程序根目录中。具有标识符的资源必须放置在/resourcesWeb 应用程序根目录下的目录中,例如/resources/<resourceIdentifier>.
  • \n
  • 在类路径中。具有标识符的资源必须存在于META-INF/resources目录下的类路径中,同样为META-INF/resources/<resourceIdentifier>. 在 Web 应用程序中,我注意到该目录应该是父类加载器中的Web Application Root/WEB-INF/classes/META-INF/resources目录之一或META-INF/resources目录之一,甚至是类路径中存在的 JAR 中的目录。显然,最后一个选项是由 JSF 2 库/框架(如 PrimeFaces)采用的选项。
  • \n
\n\n

<resourceIdentifier>除了资源名称本身之外,JSF 规范还指定了语言环境、库版本和资源版本的组成方式。ResourceHandlerAPI 文档中对此进行了简洁的处理:

\n\n
\n

包装资源

\n\n

ResourceHandler 为资源定义了基于路径的打包约定。ResourceHandler 的默认实现必须支持\n 在类路径或 Web 应用程序根目录中打包资源。\n 请参阅概述摘要中链接的规范散文文档的 JSF.2.6.1 节,了解打包的规范规范\n资源。

\n\n

简而言之,默认实现必须支持将资源打包在Web应用程序根目录下\n

\n\n
resources/<resourceIdentifier>\n
Run Code Online (Sandbox Code Playgroud)\n\n

相对于 Web 应用程序根目录。

\n\n

对于默认实现,打包在类路径中的资源必须驻留在 JAR 条目名称下

\n\n
META-INF/resources/<resourceIdentifier>\n
Run Code Online (Sandbox Code Playgroud)\n\n

由几个段组成,指定如下。

\n\n
[localePrefix/][libraryName/][libraryVersion/]resourceName[/resourceVersion]\n
Run Code Online (Sandbox Code Playgroud)\n\n

ResourceIdentifier 中的任何段都不能是相对路径,\n 例如 \xe2\x80\x98../otherLibraryName\xe2\x80\x99。实现不需要支持 JAR 打包情况的libraryVersion 和resourceVersion 段。

\n\n

请注意,resourceName 是唯一必需的段。

\n
\n\n

根据上述内容,以下方法可能有效:

\n\n
<h:outputStylesheet library="com/testing/test/html/css" name="style.xcss" />\n
Run Code Online (Sandbox Code Playgroud)\n\n

前提是样式表存在于位于上述两个区域之一的style.xcss目录结构中。com/testing/test/html/css根据您的需要将其放置在上下文根之外,唯一可能的选项是Web Application Root/WEB-INF/classes/META-INF/resources类路径中的任何其他合适的目录/JAR(包含目录META-INF/resources。当然,假设 RichFaces 不提供它) a 的自己的实现ResourceHandler;如果它确实提供了一个,您应该看看它如何扩展默认实现以允许将资源放置在其他地方。

\n\n
\n\n

在莫贾拉,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值不是由这些类生成的,而是由负责生成页面输出的渲染器生成的。

\n

  • 注意:这个答案在一方面是错误的:根据 JSF 规范,libraryName 中的斜杠 (/) 字符是非法的:http://java.net/projects/javaserverfaces-spec-public/lists/jsr344-experts/archive/ 2012-03/留言/26 (2认同)