用JSF框架时,当一个JSP页面里,JSF TAG与JSTL TAG都存在的时候,它们之间有没有联系?
对此,做了以下测试(JSF 1.2 JSTL 1.2 Server:Tomcat):
JSP代码
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<HTML>
<HEAD>
</HEAD>
<f:view beforePhase="#{testBean.doMethod}">
<p>By JSF TAG
<br>
Bean Created Time :
<h:outputText value="#{testBean.beanCreateTime}" />
<br>
Bean Method Called Time :
<h:outputText value="#{testBean.methodCalledTime}" />
<br>
<br>
By JSTL TAG
<br>
Bean Created Time :
<c:out value="${testBean.beanCreateTime}"></c:out>
<br>
Bean Method Called Time :
<c:out value="${testBean.methodCalledTime}"></c:out>
<br>
<br>Test JSF TAG used in JSTL TAG
<br>
<c:if test="${not empty testBean.beanCreateTime}">
Bean Created Time:
<h:outputText value="#{testBean.beanCreateTime}" />
<br>
</c:if>
<c:if test="${not empty testBean.methodCalledTime}">
Bean Method Called Time :
<h:outputText value="#{testBean.methodCalledTime}" />
<br>
</c:if>
</p>
</f:view>
</HTML>
import javax.faces.event.PhaseEvent;
public class TestBean {
String beanCreateTime = null;
String methodCalledTime = null;
public TestBean() {
long now = System.nanoTime();
beanCreateTime = String.valueOf(now);
System.out.println("beanCreateTime=" + beanCreateTime);
}
public void doMethod(PhaseEvent event) {
long now = System.nanoTime();
methodCalledTime = String.valueOf(now) + " PhaseID=" + event.getPhaseId();
}
public String getBeanCreateTime() {
return beanCreateTime;
}
public void setBeanCreateTime(String time) {
this.beanCreateTime = time;
}
public String getMethodCalledTime() {
return methodCalledTime;
}
public void setMethodCalledTime(String initTime) {
this.methodCalledTime = initTime;
}
}
faces-config.xml
<managed-bean> <description>TestBean</description> <managed-bean-name>testBean</managed-bean-name> <managed-bean-class> com.test.TestBean</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean>
执行JSP页面结果如下:
Bean Created Time : 89317663431525
Bean Method Called Time : 89317686242525 PhaseID=RENDER_RESPONSE 6
By JSTL TAG
Bean Created Time : 89317663431525
Bean Method Called Time :
Test JSF TAG used in JSTL TAG
Bean Created Time: 89317663431525
可以看出
1.由JSF创建出的bean可以被JSTL TAG直接使用
2.在bean的构造函数里赋值的属性可以被JSF TAG和JSTL TAG两方使用,不会有问题(如上面的beanCreateTime)。但是在JSF TAG调用的Method里赋值的属性只可以被JSF TAG使用(如methodCalledTime)
说明bean先被JSF创建,然后优先解析JSTL TAG,再解析JSF TAG
所以JSTL TAG里面如果包含JSF TAG的话,就会有冲突
另外如果JSP里加入了如下代码用来创建bean的话
<jsp:useBean id="testBean" class="com.test.TestBean" scope="request"></jsp:useBean>
JSF TAG与jsp:useBean之间的关联发现有如下几种情况
第一种情况: 如果这里的scope是和 faces-config里定义的managed-bean-scope是一致的话,那么效果与没有这段代码时是一样的
第二种情况:当这里的scope是request,而 faces-config里是session时,执行情况如下
第一次执行 : JSF和jsp:useBean各创建一个Bean实例,JSF TAG用的是JSF创建的, JSTL用的是jsp:useBean创建的
Bean Created Time : 92738654759473
Bean Method Called Time : 92738655964375 PhaseID=RENDER_RESPONSE 6
By JSTL TAG
Bean Created Time : 92738655272946
Bean Method Called Time :
Test JSF TAG used in JSTL TAG
Bean Created Time: 92738654759473
页面刷新一次后: JSF的scope是session,所以不会再次创建,jsp:useBean会在每次刷新时重新创建一次,且会覆盖JSF创建的
Bean Created Time : 92827106721384
Bean Method Called Time : 92827107836889 PhaseID=RENDER_RESPONSE 6
By JSTL TAG
Bean Created Time : 92827106721384
Bean Method Called Time :
Test JSF TAG used in JSTL TAG
Bean Created Time: 92827106721384
第三种情况:当这里的scope是session,而 faces-config里是request时,执行情况如下
第一次执行 :
Bean Created Time : 93666788381763
Bean Method Called Time : 93666790423084 PhaseID=RENDER_RESPONSE 6
By JSTL TAG
Bean Created Time : 93666788381763
Bean Method Called Time :
Test JSF TAG used in JSTL TAG
Bean Created Time: 93666788381763
页面刷新一次后:
Bean Created Time : 93666788381763
Bean Method Called Time : 93719730795394 PhaseID=RENDER_RESPONSE 6
By JSTL TAG
Bean Created Time : 93666788381763
Bean Method Called Time : 93666790423084 PhaseID=RENDER_RESPONSE 6
Test JSF TAG used in JSTL TAG
Bean Created Time: 93666788381763
Bean Method Called Time : 93719730795394 PhaseID=RENDER_RESPONSE 6
后台bean仅以session级方式实例化一次后,在同一个session里不会再次被创建
第四种情况: 当这里的scope是page,而 faces-config里是request时,执行情况如下
第一次执行 :
JSP:
Bean Created Time : 94597696039859
Bean Method Called Time : 94597697290856 PhaseID=RENDER_RESPONSE 6
By JSTL TAG
Bean Created Time : 94597696039859
Bean Method Called Time :
Test JSF TAG used in JSTL TAG
Bean Created Time: 94597696039859
后台log:
beanCreateTime=94597696039859
页面刷新一次后:
Bean Created Time : 94736992042843
Bean Method Called Time : 94736992690970 PhaseID=RENDER_RESPONSE 6
By JSTL TAG
Bean Created Time : 94736992042843
Bean Method Called Time :
Test JSF TAG used in JSTL TAG
Bean Created Time: 94736992042843
beanCreateTime=94597696039859
beanCreateTime=94736991359795
beanCreateTime=94736992042843
从上面现象看,每次JSF与jsp:useBean各创建一个beang实例,jsp:useBean创建的覆盖JSF创建的
第五种情况: 当这里的scope是page,而 faces-config里是session时,执行情况如下
JSF创建一次后不会再次创建,jsp:useBean每次创建一个bean实例,在TAG使用上互相不干扰:
第一次执行:
Bean Created Time : 108104069197900
Bean Method Called Time : 108104070863475 PhaseID=RENDER_RESPONSE 6
By JSTL TAG
Bean Created Time : 108104069197900
Bean Method Called Time :
Test JSF TAG used in JSTL TAG
Bean Created Time: 108104069197900
beanCreateTime=108104069197900
页面刷新一次后:
Bean Created Time : 108104069197900
Bean Method Called Time : 108170882535908 PhaseID=RENDER_RESPONSE 6
By JSTL TAG
Bean Created Time : 108170881005267
Bean Method Called Time :
Test JSF TAG used in JSTL TAG
Bean Created Time: 108104069197900
beanCreateTime=108104069197900
beanCreateTime=108170881005267