Bal*_*usC 224 resources jsf jsf-2
在JSF <h:outputStylesheet>
,<h:outputScript>
和<h:graphicImage>
组件具有library
属性.这是什么以及如何使用它?Web上有很多示例,它们使用如下公共内容/文件类型css
,js
以及img
(或image
)作为库名称,具体取决于所使用的标记:
<h:outputStylesheet library="css" name="style.css" />
<h:outputScript library="js" name="script.js" />
<h:graphicImage library="img" name="logo.png" />
Run Code Online (Sandbox Code Playgroud)
它有用吗?library
这些示例中的值似乎只是重复标记名称已经表示的内容.对于<h:outputStylesheet>
它来说,基于标签名称已经很明显它代表了一个"CSS库".与以下内容有什么不同,它们的工作方式相同?
<h:outputStylesheet name="css/style.css" />
<h:outputScript name="js/script.js" />
<h:graphicImage name="img/logo.png" />
Run Code Online (Sandbox Code Playgroud)
此外,生成的HTML输出有点不同.给定URL模式的上下文路径/contextname
和FacesServlet
映射*.xhtml
,前者生成以下HTML,其库名称为请求参数:
<link rel="stylesheet" type="text/css" href="/contextname/javax.faces.resource/style.css.xhtml?ln=css" />
<script type="text/javascript" src="/contextname/javax.faces.resource/script.js.xhtml?ln=js"></script>
<img src="/contextname/javax.faces.resource/logo.png.xhtml?ln=img" alt="" />
Run Code Online (Sandbox Code Playgroud)
而后者在URI的路径中生成以下带有库名的HTML:
<link rel="stylesheet" type="text/css" href="/contextname/javax.faces.resource/css/style.css.xhtml" />
<script type="text/javascript" src="/contextname/javax.faces.resource/js/script.js.xhtml"></script>
<img src="/contextname/javax.faces.resource/img/logo.png.xhtml" alt="" />
Run Code Online (Sandbox Code Playgroud)
后一种方法在事后看来也比前一种方法更有意义.该library
属性究竟有用吗?
Bal*_*usC 252
实际上,网上的所有这些例子,其中诸如"js","css","img"等的共同内容/文件类型被用作库名称是误导性的.
首先,让我们看看现有的JSF实现如Mojarra和MyFaces以及PrimeFaces和OmniFaces等JSF组件库如何使用它.他们中没有人以这种方式使用资源库.他们使用它(在封面下,用@ResourceDependency
或UIViewRoot#addComponentResource()
)以下方式:
<h:outputScript library="javax.faces" name="jsf.js" />
<h:outputScript library="primefaces" name="jquery/jquery.js" />
<h:outputScript library="omnifaces" name="omnifaces.js" />
<h:outputScript library="omnifaces" name="fixviewstate.js" />
<h:outputScript library="omnifaces.combined" name="[dynamicname].js" />
<h:outputStylesheet library="primefaces" name="primefaces.css" />
<h:outputStylesheet library="primefaces-aristo" name="theme.css" />
<h:outputStylesheet library="primefaces-vader" name="theme.css" />
Run Code Online (Sandbox Code Playgroud)
应该清楚的是,它基本上代表了所有这些资源通常属于的公共库/模块/主题名称.
通过这种方式,可以更容易地指定和区分这些资源属于和/或来自何处.想象一下,您碰巧primefaces.css
在自己的webapp中拥有一个资源,其中您正在重写/微调PrimeFaces的一些默认CSS; 如果PrimeFaces没有使用它自己的库名primefaces.css
,那么PrimeFaces自己的那个不会被加载,而是webapp提供的那个,这将破坏look'n'feel.
此外,当您使用自定义时ResourceHandler
,如果library
以正确的方式使用,您还可以对来自特定库的资源应用更精细的控制.如果所有组件库都为其所有JS文件使用了"js",那么ResourceHandler
如果它来自特定的组件库,它将如何区分?例如OmniFaces CombinedResourceHandler
和GraphicResourceHandler
; createResource()
检查在委托给链中的下一个资源处理程序之前检查库的方法.通过这种方式,他们知道何时创建CombinedResource
或GraphicResource
用于此目的.
值得注意的是,RichFaces做错了.它根本没有使用任何东西library
,并在其上自制了另一个资源处理层,因此无法以编程方式识别RichFaces资源.这正是为什么OmniFaces CombinedResourceHander
必须引入基于反射的黑客才能让它在RichFaces资源上运行的原因.
您自己的webapp不一定需要资源库.你最好省略它.
<h:outputStylesheet name="css/style.css" />
<h:outputScript name="js/script.js" />
<h:graphicImage name="img/logo.png" />
Run Code Online (Sandbox Code Playgroud)
或者,如果你真的需要一个,你可以给它一个更明智的通用名称,如"默认"或一些公司名称.
<h:outputStylesheet library="default" name="css/style.css" />
<h:outputScript library="default" name="js/script.js" />
<h:graphicImage library="default" name="img/logo.png" />
Run Code Online (Sandbox Code Playgroud)
或者,当资源特定于某些主Facelets模板时,您还可以为其指定模板的名称,以便更容易相互关联.换句话说,它更多用于自我纪录目的.例如在/WEB-INF/templates/layout.xhtml
模板文件中:
<h:outputStylesheet library="layout" name="css/style.css" />
<h:outputScript library="layout" name="js/script.js" />
Run Code Online (Sandbox Code Playgroud)
还有一个/WEB-INF/templates/admin.xhtml
模板文件:
<h:outputStylesheet library="admin" name="css/style.css" />
<h:outputScript library="admin" name="js/script.js" />
Run Code Online (Sandbox Code Playgroud)
有关实际示例,请查看OmniFaces展示源代码.
或者,当您想要在多个Web应用程序上共享相同的资源并基于与此答案相同的示例为此创建"通用"项目时,该答案又在Web应用程序中作为JAR嵌入/WEB-INF/lib
,那么也将其引用为库(名称可供您自由选择; OmniFaces和PrimeFaces等组件库也可以这样工作):
<h:outputStylesheet library="common" name="css/style.css" />
<h:outputScript library="common" name="js/script.js" />
<h:graphicImage library="common" name="img/logo.png" />
Run Code Online (Sandbox Code Playgroud)
另一个主要优点是您可以在您自己的webapp提供的资源上以正确的方式应用资源库版本控制(这不适用于嵌入在JAR中的资源).您可以在库文件夹中创建直接子子文件夹,并在\d+(_\d+)*
模式中使用名称来表示资源库版本.
WebContent
|-- resources
| `-- default
| `-- 1_0
| |-- css
| | `-- style.css
| |-- img
| | `-- logo.png
| `-- js
| `-- script.js
:
Run Code Online (Sandbox Code Playgroud)
使用此标记时:
<h:outputStylesheet library="default" name="css/style.css" />
<h:outputScript library="default" name="js/script.js" />
<h:graphicImage library="default" name="img/logo.png" />
Run Code Online (Sandbox Code Playgroud)
这将生成以下HTML,其库版本为v
参数:
<link rel="stylesheet" type="text/css" href="/contextname/javax.faces.resource/css/style.css.xhtml?ln=default&v=1_0" />
<script type="text/javascript" src="/contextname/javax.faces.resource/js/script.js.xhtml?ln=default&v=1_0"></script>
<img src="/contextname/javax.faces.resource/img/logo.png.xhtml?ln=default&v=1_0" alt="" />
Run Code Online (Sandbox Code Playgroud)
因此,如果您已编辑/更新了某些资源,那么您只需将版本文件夹复制或重命名为新值即可.如果您有多个版本文件夹,那么JSF ResourceHandler
将根据数字排序规则自动从最高版本号提供资源.
因此,当复制/重命名resources/default/1_0/*
文件夹时,resources/default/1_1/*
如下所示:
WebContent
|-- resources
| `-- default
| |-- 1_0
| | :
| |
| `-- 1_1
| |-- css
| | `-- style.css
| |-- img
| | `-- logo.png
| `-- js
| `-- script.js
:
Run Code Online (Sandbox Code Playgroud)
然后最后一个标记示例将生成以下HTML:
<link rel="stylesheet" type="text/css" href="/contextname/javax.faces.resource/css/style.css.xhtml?ln=default&v=1_1" />
<script type="text/javascript" src="/contextname/javax.faces.resource/js/script.js.xhtml?ln=default&v=1_1"></script>
<img src="/contextname/javax.faces.resource/img/logo.png.xhtml?ln=default&v=1_1" alt="" />
Run Code Online (Sandbox Code Playgroud)
这将强制webbrowser直接从服务器请求资源,而不是在第一次请求具有已更改参数的URL时从缓存中显示具有相同名称的资源.这样,当需要检索更新的CSS/JS资源时,最终用户不需要进行硬刷新(Ctrl + F5等).
请注意,JAR文件中包含的资源无法进行库版本控制.你需要一个自定义ResourceHandler
.另请参见如何在jar中使用JSF版本控制资源.
归档时间: |
|
查看次数: |
116917 次 |
最近记录: |