JSF 2 提供了定义和访问资源的标准机制。您将自己的资源放到名为 resources 的顶级目录下,并使用一些 JSF 2 标记来在视图中访问这些资源。例如,图 4 展示了 places 应用程序的资源:
图 4. places 应用程序的资源
对资源的惟一需求是它必须位于 resources 目录或 resources 目录的子目录中。可以随意命名 resources 目录的子目录。
在您的视图代码中,可以使用两个 JSF 2 标记访问资源:<h:outputScript> 和 <h:outputStylesheet>。这些标记可以结合用于 JSF 2 的 <h:head> 和 <h:body> 标记,如清单 12 所示:
清单 12. 在 XHTML 中访问资源
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
...
</h:head>
<h:body>
<h:outputStylesheet library="css" name="styles.css" target="body"/>
<h:outputScript library="javascript" name="util.js" target="head"/>
...
</h:body>
</html>
<h:outputScript> 和 <h:outputStylesheet> 标记有两个属性,分别指定了脚本或样式表:library 和 name。library 名称对应于 resources 目录下的子目录,这是保存资源的位置。例如,如果在 resources/css/en 目录中有一个样式表,那么 library 将为 css/en。name 属性是资源本身的名称。
注:
- <h:outputScript> 和 <h:outputStylesheet> 应当位于<h:head>或<h:body>中,不能位于<html>中,否则无效。
- 使用这两个标记可以确保引用资源的url不随页面相对资源的路径变化而变化,极大的提升了页面的可流动性。
可重新定位的资源
开发人员需要能够在页面中指定想要呈现他们的资源的位置。例如,如果将 JavaScript 放在页面体中,浏览器将在加载页面时执行 JavaScript。另一方面,如果将 JavaScript 放到页面的头部,那么 JavaScript 只有在得到调用时才会被执行。由于资源的放置位置会影响它的使用方式,因此需要能够指定希望在哪些位置显示资源。
JSF 2 资源是可重新定位的,这意味着您可以在页面中指定希望放置资源的位置。您将使用 target 属性指定位置;比如,在 清单 12 中,我将 CSS 放到页面体中,而将 JavaScript 放到页面头部中。
有些情况下,需要使用 JSF 表达式语言(EL)访问资源。比如,清单 13 展示了如何使用 <h:graphicImage> 访问一个图像:
清单 13. 使用 JSF 表达式语言访问资源
<h:graphicImage value="#{resource['images:cloudy.gif']}"/>
清单 13 的非 EL 备选方法
无可否认,清单 13 中的语法不是很直观。它访问了一个 JSF 为了存储资源而创建的地图,因此很少需要使用这种语法。实际上,可以使用 <h:graphicImage/> 访问图像,而不需要使用 EL,比如:<h:graphicImage library="images" name="cloudy.gif"/>
在 EL 表达式内访问资源的语法是 resource['LIBRARY:NAME'],其中 LIBRARY 和 NAME 对应于 <h:outputScript> 和 <h:outputStylesheet> 标记的 library 和 name 属性。
注意:如果你引入css资源时,其中涉及到图片文件的路径引用会有点问题,当我们的css文件引用同目录下的images中的图片时,常常是如:../images/1.gif路径,但是在这里是错误的,你不妨看下客户端的源码时,会看到JSF2将 <h:outputStylesheet>中的路径解析为/advang-war/javax.faces.resource/common.css.xhtml?ln=style 类似格式,可见,这个CSS文件是放置在应用根目录下的 javax.faces.resources文件夹中,这样真正的路径应该都相对于该目录,于是,正确的路径是../resources/images/1.gif.