在本练习中,将创建一个 JSF 受管 Bean。受管 Bean 中的方法用于显示 JSF 页面中的数据,以及访问 helper 类中的方法以检索记录。JSF 2.0 规范允许在 Bean 类中使用标注以将类标识为 JSF 受管 Bean,以及指定范围和 Bean 名称。
要创建受管 Bean,请执行以下步骤。
在调用受管 Bean 中的方法时,将使用 Bean 名称 filmController 作为 JSF 页面 index.xhtml 中的 inputText 和 commandButton 的值。
单击“完成”后,IDE 创建 Bean 类并在编辑器中打开该类。IDE 添加了 @ManagedBean 和 @SessionScoped 标注以及 Bean 名称。
@ManagedBean(name="filmController") @SessionScoped public class FilmController { /** Creates a new instance of FilmController */ public FilmController() { } }
@ManagedBean(name="filmController") @SessionScoped public class FilmController { int startId; int endId; DataModel filmTitles; FilmHelper helper; private int recordCount = 1000; private int pageSize = 10; private Film current; private int selectedItemIndex; }
/** Creates a new instance of FilmController */ public FilmController() { helper = new FilmHelper(); startId = 1; endId = 10; } public FilmController(int startId, int endId) { helper = new FilmHelper(); this.startId = startId; this.endId = endId; } public Film getSelected() { if (current == null) { current = new Film(); selectedItemIndex = -1; } return current; } public DataModel getFilmTitles() { if (filmTitles == null) { filmTitles = new ListDataModel(helper.getFilmTitles(startId, endId)); } return filmTitles; } void recreateModel() { filmTitles = null; }
public boolean isHasNextPage() { if (endId + pageSize <= recordCount) { return true; } return false; } public boolean isHasPreviousPage() { if (startId-pageSize > 0) { return true; } return false; } public String next() { startId = endId+1; endId = endId + pageSize; recreateModel(); return "index"; } public String previous() { startId = startId - pageSize; endId = endId - pageSize; recreateModel(); return "index"; } public int getPageSize() { return pageSize; } public String prepareView(){ current = (Film) getFilmTitles().getRowData(); return "browse"; } public String prepareList(){ recreateModel(); return "index"; }
返回 "index" 或 "browse" 的方法将提示 JSF 导航处理程序尝试打开名为 index.xhtml 或 browse.xhtml 的页面。JSF 2.0 规范允许在使用 Facelets 技术的应用程序中使用隐式导航规则。此应用程序中,没有在 faces-config.xml 中配置任何导航规则。导航处理程序将尝试在应用程序中查找合适的页面。
public String getLanguage() { int langID = current.getLanguageByLanguageId().getLanguageId().intValue(); String language = helper.getLangByID(langID); return language; } public String getActors() { List actors = helper.getActorsByID(current.getFilmId()); StringBuffer totalCast = new StringBuffer(); for (int i = 0; i < actors.size(); i++) { Actor actor = (Actor) actors.get(i); totalCast.append(actor.getFirstName()); totalCast.append(" "); totalCast.append(actor.getLastName()); totalCast.append(" "); } return totalCast.toString(); } public String getCategory() { Category category = helper.getCategoryByID(current.getFilmId()); return category.getName(); }
您可以在编辑器中使用代码完成以帮助键入代码。
在本练习中,将创建两个 Web 页以显示数据。您将修改 IDE 生成的 index.xhtml 以添加一个表,以便显示数据库中的影片。然后创建 browse.xhtml,以便在单击表中的 "View" 链接时显示影片的详细信息。还会创建一个 JSF 模板页面以供 index.xhtml 和 browse.xhtml 使用。
有关使用 JSF 2.0 和 Facelets 模板的更多信息,请参见 JavaServer Faces 2.0 简介。
首先,创建 JSF Facelets 模板 template.xhtml,在创建 index.xhtml 和 browse.xhtml 页面时将使用该模板。
单击“完成”后,template.xhtml 文件在编辑器中打开。该模板包含以下缺省代码。
<h:body> <div id="top" class="top"> <ui:insert name="top">Top</ui:insert> </div> <div id="content" class="center_content"> <ui:insert name="content">Content</ui:insert> </div> </h:body>
<div id="content" class="center_content"> <ui:insert name="body">Content</ui:insert> </div>
index.xhtml 和 browse.xhtml 中的 <ui:define name="body"> 元素包含的内容将插入到使用模板中的 <ui:insert name="body">Content</ui:insert> 指定的位置。
在创建 Web 应用程序时,IDE 将自动生成 index.xhtml 页面。在本练习中,将修改该页面以显示影片名称列表。JSF 页面调用 JSF 受管 Bean FilmController 中的方法以检索影片列表,然后显示一个包含影片名称和说明的表格。
“新建项目”向导生成了以下缺省 index.xhtml 页面。
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"> <h:head> <title>Facelet Title</title> </h:head> <h:body> Hello from Facelets </h:body> </html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets"> <ui:composition template="./template.xhtml"> <ui:define name="body"> <h:form> </h:form> </ui:define> </ui:composition> </html>
开始键入标记时,IDE 将添加 xmlns:ui="http://java.sun.com/jsf/facelets" 标记库声明。
<ui:composition> 和 <ui:define> 元素将与所创建的页面模板结合使用。<ui:composition> 元素引用此页面将使用的模板的位置。<ui:define> 元素引用包含的代码将占用的模板位置。
<ui:define name="body"> <h:form> <h:commandLink action="#{filmController.previous}" value="Previous #{filmController.pageSize}" rendered="#{filmController.hasPreviousPage}"/> <h:commandLink action="#{filmController.next}" value="Next #{filmController.pageSize}" rendered="#{filmController.hasNextPage}"/> </h:form> </ui:define>
<h:form styleClass="jsfcrud_list_form"> <h:commandLink action="#{filmController.previous}" value="Previous #{filmController.pageSize}" rendered="#{filmController.hasPreviousPage}"/> <h:commandLink action="#{filmController.next}" value="Next #{filmController.pageSize}" rendered="#{filmController.hasNextPage}"/> <h:dataTable value="#{filmController.filmTitles}" var="item" border="0" cellpadding="2" cellspacing="0" rowClasses="jsfcrud_odd_row,jsfcrud_even_row" rules="all" style="border:solid 1px"> <h:column> <f:facet name="header"> <h:outputText value="Title"/> </f:facet> <h:outputText value="#{item.title}"/> </h:column> <h:column> <f:facet name="header"> <h:outputText value="Description"/> </f:facet> <h:outputText value="#{item.description}"/> </h:column> <h:column> <f:facet name="header"> <h:outputText value=" "/> </f:facet> <h:commandLink action="#{filmController.prepareView}" value="View"/> </h:column> </h:dataTable> <br/> </h:form>
现在,index 页面将显示数据库中的影片名称列表。表中的每一行都包含 "View" 链接,用于调用受管 Bean 中的 prepareView 方法。prepareView 方法返回 "browse" 并打开 browse.xhtml。
键入 <f:facet> 标记时,IDE 将添加 xmlns:f="http://java.sun.com/jsf/core 标记库声明。
现在,将创建 browse.xhtml 页面以显示所选影片的详细信息。可以使用“Facelets 模板客户端”向导基于所创建的 JSF Facelets 模板 template.xhtml 创建该页面。
单击“完成”时,browse.xhtml 文件在编辑器中打开,其中包含以下代码。
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets" template="./template.xhtml"> <ui:define name="top"> top </ui:define> <ui:define name="body"> body </ui:define> </ui:composition>
您可以看到新文件指定了 template.xhtml 文件,并且 <ui:define> 标记具有属性 name="body"。
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets" template="./template.xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"> <ui:define name="top"> top </ui:define> <ui:define name="body"> <h:form> <h:panelGrid columns="2"> <h:outputText value="Title:"/> <h:outputText value="#{filmController.selected.title}" title="Title"/> <h:outputText value="Description"/> <h:outputText value="#{filmController.selected.description}" title="Description"/> <h:outputText value="Genre"/> <h:outputText value="#{filmController.category}"/> <h:outputText value="Cast"/> <h:outputText value="#{filmController.actors}"/> <h:outputText value="Film Length"/> <h:outputText value="#{filmController.selected.length} min" title="Film Length"/> <h:outputText value="Language"/> <h:outputText value="#{filmController.language}" title="Film Length"/> <h:outputText value="Release Year"/> <h:outputText value="#{filmController.selected.releaseYear}" title="Release Year"> <f:convertDateTime pattern="MM/dd/yyyy" /> </h:outputText> <h:outputText value="Rental Duration"/> <h:outputText value="#{filmController.selected.rentalDuration}" title="Rental DUration"/> <h:outputText value="Rental Rate"/> <h:outputText value="#{filmController.selected.rentalRate}" title="Rental Rate"/> <h:outputText value="Replacement Cost"/> <h:outputText value="#{filmController.selected.replacementCost}" title="Replacement Cost"/> <h:outputText value="Rating"/> <h:outputText value="#{filmController.selected.rating}" title="Rating"/> <h:outputText value="Special Features"/> <h:outputText value="#{filmController.selected.specialFeatures}" title="Special Features"/> <h:outputText value="Last Update"/> <h:outputText value="#{filmController.selected.lastUpdate}" title="Last Update"> <f:convertDateTime pattern="MM/dd/yyyy HH:mm:ss" /> </h:outputText> </h:panelGrid> <br/> <br/> <h:commandLink action="#{filmController.prepareList}" value="View All List"/> <br/> </h:form> </ui:define> </ui:composition> </html>
您可以看到 browse.xhtml 和 index.xhtml 使用相同的页面模板。
应用程序的基础部分现已完成。现在,您可以运行应用程序以检查其是否正常运行。
IDE 保存所有更改过的文件,构建应用程序并将应用程序部署到服务器。IDE 将打开浏览器窗口并指向 URL http://localhost:8080/DVDStore/ 以显示影片列表。
您可以采用下列方法下载本教程的解决方案(作为一个项目)。
单击“完成”后,IDE 会将本地文件夹初始化为 Subversion 资源库,并签出项目源代码。
注意: