jstl是标准的jsp标签,在jsp中使用非常方便,但却不能直接在jsf中使用,虽然表面上看起来使用没有什么区别,那是因为jsf(facelets)对jstl标签的功能进行了重新实现,以便能在jsf中正常使用。
jstl是基于标准jsp技术的,而jsf与jsp是完全不同的,jsp只是用来显示,而jsf除了显示还有更多功能,比如table的更新等。
jstl重新实现后也只是在构造页面组件树方面,他本身并不产生任何jsf组件,大家可以参考facelets中的jstl实现源码。
注意事项:
1)<c:if标签不能在<h:dataTable等具有循环性质的组件内使用。
<h:dataTable id="itemList" value="#{ents}" var="ent">
<h:column>
<f:facet name="header">long1</f:facet>
<c:if test="#{ent.double1>3}"><h:outputText value="#{ent.double1}" /></c:if>
</h:column>
其中的<h:outputText value="#{ent.double1}" />总是不能显示出来,因为<c:if只是在构造页面组件树时才执行,但是构造组件时h:dataTable 中的var是不可用的,所以#{ent.double1}是没有值的,<h:outputText value="#{ent.double1}" />不会被添加到组件树里,那么当table显示时就没法显示<h:outputText value="#{ent.double1}" />了。
但是<ui:repeat与之不同,他是个jsf组件,会被添加到组件树中,与dataTable的集中相同。
2)jstl标签应该成套使用,即if出现在foreach中是没问题的。
<c:forEach items="#{ents}" var="e">
e.double1:<h:outputText value="#{e.double1}" />\
e.double1 test:<c:if test="#{e.double1>3}"><h:outputText value="#{e.double1}" /></c:if>\
e.double1 test2:<c:if test="#{e.double1>3}">#{e.double1}</c:if>
<br/>
</c:forEach>这些都没问题
这实际上会产生很多组件到组件树里,而不像h:table那些只会产生一个组件到树里,跟table的记录数没有关系。
3)动态编程
通过循环添加多个tab,而不用在程序中添加多个tab组件到组件树中,这与直接在<rich:tabPanel 下面写几个tab效果相同。使用ui:repeat是不行的,他不会创建多个tab组件,并且将repeat组件添加到了tabPanel 下面,导致tabPanel 结构不正确
<rich:tabPanel
<c:forEach var="menu" items="#{menuBean.menuHeader}"
varStatus="status">
<rich:tab label="#{menu.label_name}" name="#{menu.label_name}" rendered="true"
id="rrr_#{status.index}" >
<a4j:support event="onlabelclick" ajaxSingle="true" actionListener="#{menuBean.tabclick}"/>
<a4j:support event="eventsQueue" ajaxSingle="true"/>
<a4j:include viewId="#{menu.url}"/>
</rich:tab>
</c:forEach>
参见faceslet源码ForEachHandler的apply方法
每到第6阶段都要执行apply方法,循环执行下面
4)定义复合组件时使用