同一JSF主页面下,如果要在几个subviews之间切换,最简单的方法是:
<jsp:include page="#{myBean.currentInclude}" />
但是该方法只能用于JSF 1.2 + JSP 2.1环境下,在更早的版本下,以上的表达式是不合法的。
最常用的方法是利用f:subview和Rendered属性进行硬编程,如下:
<f:subview id="includePage1" rendered="#{myBean.currentInclude == 'includePage1'}">
<jsp:include page="includePage1.jsp" />
</f:subview>
<f:subview id="includePage2" rendered="#{myBean.currentInclude == 'includePage2'}">
<jsp:include page="includePage2.jsp" />
</f:subview>
<f:subview id="includePage3" rendered="#{myBean.currentInclude == 'includePage3'}">
<jsp:include page="includePage3.jsp" />
</f:subview>
<jsp:include page="includePage1.jsp" />
</f:subview>
<f:subview id="includePage2" rendered="#{myBean.currentInclude == 'includePage2'}">
<jsp:include page="includePage2.jsp" />
</f:subview>
<f:subview id="includePage3" rendered="#{myBean.currentInclude == 'includePage3'}">
<jsp:include page="includePage3.jsp" />
</f:subview>
当MyBean.java中getCurrentInclude()方法被调用的时候,返回所要include的页面,这种方法的最大问题是你必须将每个可能include到的页面都硬编程到主页面中。
另外一种常用的方法是利用h:panelGroup标签,这种方法要求include的页面中必须已经使用f:subview标签,这种方法和上一种大同小异,所以仍然摆脱不了上面的缺点:
<h:panelGroup rendered="#{myBean.currentInclude == 'includePage1'}">
<jsp:include page="includePage1.jsp" />
</h:panelGroup>
<h:panelGroup rendered="#{myBean.currentInclude == 'includePage2'}">
<jsp:include page="includePage2.jsp" />
</h:panelGroup>
<h:panelGroup rendered="#{myBean.currentInclude == 'includePage3'}">
<jsp:include page="includePage3.jsp" />
</h:panelGroup>
<jsp:include page="includePage1.jsp" />
</h:panelGroup>
<h:panelGroup rendered="#{myBean.currentInclude == 'includePage2'}">
<jsp:include page="includePage2.jsp" />
</h:panelGroup>
<h:panelGroup rendered="#{myBean.currentInclude == 'includePage3'}">
<jsp:include page="includePage3.jsp" />
</h:panelGroup>
小技巧:
使用scriptlets,jsp:include 标签可以使用scriptlets,一个必要条件是managed bean 的作用域是session。如果managed bean的作用域是request,所遇到的问题和上面两种有些类似。
在faces-config文件中进行配置:
<managed-bean>
<managed-bean-name>myBean</managed-bean-name>
<managed-bean-class>mypackage.MyBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean-name>myBean</managed-bean-name>
<managed-bean-class>mypackage.MyBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
主页面中的代码如下:
<%
mypackage.MyBean myBean = (mypackage.MyBean) session.getAttribute("myBean");
if (myBean == null) { // First-time initialization of bean not done yet.
myBean = new mypackage.MyBean();
}
String includePage = myBean.getIncludePage() + ".jsp";
%> <f:view>
<html>
<head>
</head>
<body>
<jsp:include page="<%= includePage %>" />
</h:panelGroup>
</html>
</f:view>
mypackage.MyBean myBean = (mypackage.MyBean) session.getAttribute("myBean");
if (myBean == null) { // First-time initialization of bean not done yet.
myBean = new mypackage.MyBean();
}
String includePage = myBean.getIncludePage() + ".jsp";
%> <f:view>
<html>
<head>
</head>
<body>
<h:panelGroup rendered="#{myBean.includePage != null}">
<jsp:include page="<%= includePage %>" />
</h:panelGroup>
</body>
</html>
</f:view>
注意:不要用f:subview替换掉例子中的h:panelGroup,每个include页面的f:subview标签的id属性必须是唯一的。
backing bean:MyBean.java的相关代码如下:
private String includePage;
public String getIncludePage() {
if (...) { // Do your thing, this is just a basic example.
includePage = "includePage1";
} else if (...) {
includePage = "includePage2";
} else if (...) {
includePage = "includePage3";
}
return includePage;
if (...) { // Do your thing, this is just a basic example.
includePage = "includePage1";
} else if (...) {
includePage = "includePage2";
} else if (...) {
includePage = "includePage3";
}
return includePage;
}
翻译自:http://balusc.blogspot.com/2007/01/dynamic-jsf-subviews.html