程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 使用JavaServer Faces構建Apache Geronimo應用程序,第5部分

使用JavaServer Faces構建Apache Geronimo應用程序,第5部分

編輯:關於JAVA

將 JSF 應用程序與 Spring 集成

開始之前

本教程向 Java 程序員介紹如何使用 JSF 組件來構建具有高度交互性的部署在 Apache Geronimo 上的 Java EE 應用程序。本教程假設 讀者將使用 Eclipse IDE 作為開發平台。

關於本教程

本教程講解 Spring Framework,這是一個大型(且非常完整的)Web 應用程序框架,可以將它與 JSF 應用程序結合使用。我們將使用 Spring 繼續開發我們這個開發人員論壇示例應用程序的登錄頁面的前端。

關於本系列

本教程是關於使用 JSF 構建 Apache Geronimo 應用程序的系列教程(共分五部分)的最後一部分。下面是整個系列教程的摘要:

第 1 部分:使用 Eclipse 和 Apache MyFaces Core 構建基本的應用程序 介紹了如何將 JSF 標准的 Apache MyFaces 實現與免費應用 服務器 Geronimo(同樣來自 Apache)結合使用。這個教程向您展示了如何使用 Eclipse IDE 的 Web Tool Platform(WTP)構建 JSF 應 用程序。

第 2 部分:在 JavaServer Faces 中使用 Tomahawk 展示了如何將 Apache Tomahawk 組件與 Geronimo 應用程序集成在一起。 Tomahawk 提供了若干個自定義組件,可與 JSF 完全兼容。

第 3 部分:在 JavaServer Faces 中使用 ajax4jsf 展示了如何使用 Sun 的免費開放源碼框架 ajax4jsf 將 Ajax 功能添加到 Geronimo 應用程序中。

第 4 部分:使用 Apache Trinidad 組件擴展 JSF 介紹了如何將來自 Apache Trinidad(ADF Faces 的開放源碼版本)的組件集成到 Geronimo 應用程序中,以增強 JSF 應用程序的界面。

第 5 部分:將 JSF 應用程序與 Spring 集成 展示了如何將 JSF 應用程序與 Spring 框架集成。Spring 是一個流行的框架,它使 Geronimo 開發人員能更輕松地構建 Java EE 應用程序。

系統需求

必須具備以下工具才能學習本教程:

Geronimo,Apache 的 Java EE 服務器項目。Geronimo 提供了 Tomcat 和 Jetty 兩種風格,選用哪種取決於您的需求。我們使用 Jetty(1.1 版),因為它比較小。

MyFaces,Apache 的 JSF 實現。請從 Apache 下載核心版本(不附帶 Tomcat)。

Spring Framework,一個強大的應用程序框架,可以與現有的 Web 應用程序集成。

Eclipse,可擴展的開放源碼 IDE,支持多種語言和平台。

Eclipse Web Tools Platform,用於向 Eclipse 中添加了 XML 和 JavaScript 編輯支持以及對 JSF 的基本支持。

在系統中安裝 Java 1.4 或更高版本。Eclipse 二進制文件附帶了它自己的 Java 運行時,但 Geronimo 和 MyFaces 則沒有(帶運行時 會使下載存檔文件顯著變大)。在本教程中,我們使用 Mac OS X 10.4 上的 Java 1.5,但應當不會有太大差異。

准備工作

在本節中,我們將導入當前的 devSignup 項目,以便在下一節開始將 Spring 功能集成到應用程序中。您還將了解 Spring Framework 以及它的一些優點。

導入 devSignup 項目

如果您還沒有閱讀本系列的前幾篇教程,至少應該下載 devSignup 示例項目(本教程末尾的 下載 部分提供了鏈接),因為稍後將需要 在其中添加功能。

第 2 部分 詳細說明了如何將項目從源存檔文件導入 Eclipse。下載 devSignup-src.zip 並按照第 2 部分中的說明進行操作,完成後 再回到這裡。確保按照第 2 部分的 “修復 devSignup 項目” 一節中的說明進行操作,否則將不能構建應用程序。

完成後,Eclipse Navigator 視圖應當類似於 圖 1。

圖 1. Eclipse 中的 devSignup 項目

現在,開始研究 Spring Framework 以及它能夠為您做什麼。

Spring Framework

Spring 是一個大型 Java Web 應用程序框架,專為使 Java 編程更輕松而設計。它能夠很好地與 Hibernate 等現有工具相集成,並隱 藏了不同 Java Database Connectivity(JDBC)實現之間的差異。它提供一個分層的設計(見 圖 2)並支持一些游泳的特性,包括:

用於應用程序及其對象的完整的輕量容器

用於事務管理的通用抽象層,它不與任何特定的 Java 環境綁定,對開發人員隱藏了低層細節(和問題)

JDBC 抽象層,它跨 JDBC 實現提供有意義的標准化的異常行為

與各種資源持有程序的集成,包括 TopLink、Hibernate、Java Data Objects(JDO)和 iBATIS SQL Maps

Spring 配置管理中集成了面向方面的編程(Aspect-Oriented Programming,AOP)

靈活的 Model View Controller(MVC)Web 應用程序框架

Spring 的主要模塊見 圖 2。

圖 2. 充滿 Java EE 縮寫詞的 Spring 體系結構

在 圖 2 中可以看到,Spring 在一個 Geronimo 應用服務器中運行,這使您能夠體會它的分層設計。Spring 允許使用 JavaBean 屬性 和配置文件注入對象;因此可以動態地添加或刪除進行協作的對象和服務。對於熟悉 Decorator 設計模式的開發人員,這種設計很相似, 但是不需要任何代碼重構;添加或刪除對象都是通過配置文件進行的。

在 Spring 中有許多高端的企業應用特性和支持,本教程不會討論這些內容,以使您集中關注如何在現有的應用程序中利用 Spring Framework。

回顧 devSignup 的 MyFaces JSF 實現

既然已經對 Spring 有了點兒了解,就應該看一些實際代碼了。

首先,看看如何讓 Developer Forum Signup 應用程序在使用 Apache MyFaces JSF 實現的 Geronimo 中運行。然後,在下一節中,將 在其中添加一些 Spring 功能。

MyFaces Developer Signup 應用程序

當前,Developer Signup 應用程序相當簡單。它顯示一個頁面,頁面上有幾個用戶可以填寫的字段,它會驗證一些數據(如果探測到無 效數據,就警告用戶),並告訴用戶操作是否成功。實際上,我們返回到本系列 第 2 部分 (“在 JavaServer Faces 中使用 Tomahawk” )中的版本,所以它只使用普通 JSF(采用 Apache MyFaces 的形式)以及幾個來自 Tomahawk 組件庫的擴展。這會提供少量功能,避免過 大的復雜性。

這個小應用程序中最重要的文件是:

web.xml —— Java EE 應用程序描述符、設置等等

faces-config.xml —— JSF 配置

geronimo-web.xml —— Geronimo 應用程序描述符

signup.jsp —— 注冊頁面和驗證

SignupData.java —— 跟蹤表單數據的 bean

在 下載 部分中可以找到這個應用程序的基本 JSF 版本的源代碼(devSignup-jsf-src.zip),可以將它裝載進 Eclipse 並進行實驗。 現在快速浏覽一下重要的源代碼文件。

devSignup web.xml

清單 1 顯示 Developer Signup 應用程序中完整的 web.xml 文件。

清單 1. Developer Signup 的 web.xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="devSignup" version="2.4"
   xmlns="http://java.sun.com/xml/ns/j2ee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
  http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

   <display-name>devSignup</display-name>

   <context-param>
     <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
     <param-value>client</param-value>
   </context-param>

   <context-param>

  <param-name>org.apache.myfaces.ALLOW_JAVASCRIPT</param-name>
     <param-value>true</param-value>
   </context-param>

   <context-param>
     <param-name>org.apache.myfaces.PRETTY_HTML</param-name>
     <param-value>true</param-value>
   </context-param>

   <context-param>

  <param-name>org.apache.myfaces.DETECT_JAVASCRIPT</param-name>
     <param-value>false</param-value>
   </context-param>

   <context-param>
     <param-name>org.apache.myfaces.AUTO_SCROLL</param-name>
     <param-value>true</param-value>
   </context-param>

   <context-param>

  <param-name>org.apache.myfaces.ADD_RESOURCE_CLASS</param-name>

<param-value>org.apache.myfaces.renderkit.html.util.DefaultAddResource
</param-value>
   </context-param>

   <context-param>

<param-name>org.apache.myfaces.CHECK_EXTENSIONS_FILTER</param-name>
     <param-value>true</param-value>
   </context-param>

   <context-param>

<param-name>org.apache.myfaces.ADD_RESOURCE_CLASS</param-name>

<param-value>org.apache.myfaces.renderkit.html.util.DefaultAddResource
</param-value>
   </context-param>

   <context-param>

<param-name>org.apache.myfaces.CHECK_EXTENSIONS_FILTER</param-name>
     <param-value>true</param-value>
   </context-param>

   <listener>

<listener-class>org.apache.myfaces.webapp.StartupServletContextListener
</listener-class>
   </listener>

   <servlet>
     <servlet-name>Faces Servlet</servlet-name>

<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
     <load-on-startup>1</load-on-startup>
   </servlet>

   <servlet-mapping>
     <servlet-name>Faces Servlet</servlet-name>
     <url-pattern>*.faces</url-pattern>
   </servlet-mapping>

   <filter>
     <filter-name>MyFacesExtensionsFilter</filter-name>

<filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</fil
ter-class>
     <init-param>
       <param-name>maxFileSize</param-name>
       <param-value>20m</param-value>
     </init-param>
   </filter>

   <filter-mapping>
     <filter-name>MyFacesExtensionsFilter</filter-name>
     <url-pattern>*.faces</url-pattern>
   </filter-mapping>

   <filter-mapping>
     <filter-name>MyFacesExtensionsFilter</filter-name>

<url-pattern>/faces/myFacesExtensionResource/*</url-pattern>
   </filter-mapping>

   <welcome-file-list>
     <welcome-file>index.jsp</welcome-file>
   </welcome-file-list>
</web-app>

這個 web.xml 文件包含幾組元素,見 表 1。

表 1. web.xml 文件中的元素

元素 描述 <web-app> Web 應用程序描述符數據的容器 <display-name> 向系統管理員顯示的應用程序名 <context-param> 鍵-值對,它們設置 Web 應用程序組件使用的各種配置值;這裡顯示的大多數是默認值,但也可以以任何方式指定,從而在應用 程序啟動日志中消除警告 <listener> 指定監聽器的類名,這個類將監聽到來的客戶機連接並決定如何處理它們 <servlet> 在這裡指定 servlet 的內部名稱、管理 servlet 組件的類的名稱以及在應用服務器啟動時是否應該裝載這個 servlet <servlet-mapping> 定義在 <servlet-name> 指定的 <servlet> 匹配時將裝載的 URL,這裡的 <servlet-name> 必須與 <servlet> 部分中指定的 <servlet-name> 匹配 <filter> 和 <filter-mapping> 在應用程序中添加一個頁面過濾器,並指定哪些 URL 需要通過這個過濾器,就像 <servlet> 和 <servlet- mapping> 對一樣 <welcome-file-list> 列出一個或多個文件名,如果將不完整的 URL 傳遞給應用程序,就應該裝載這些文件

這些都是標准的 Java EE 應用程序描述符標記;這裡沒有 JSF、MyFaces 或 Tomahawk 專用的標記。

devSignup faces-config.xml

faces-config.xml 文件(見 清單 2)設置 JSF 應用程序參數,並聲明托管 bean 以及從一個 JSF 頁面鏈接到下一個頁面的導航規則 。

清單 2. JSF 應用程序參數在 faces-config.xml 中設置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE faces-config PUBLIC
   "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
   "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">

<faces-config>
   <application>
     <locale-config>
       <default-locale>en_US</default-locale>
     </locale-config>
   </application>

   <managed-bean>
     <description>
       Data used for requesting membership in the Developer Forum.
     </description>
     <managed-bean-name>signupData</managed-bean-name>

  <managed-bean-class>devSignup.SignupData</managed-bean-class>
     <managed-bean-scope>request</managed-bean-scope>
   </managed-bean>

   <navigation-rule>
     <display-name>signup</display-name>
     <from-view-id>/signup.jsp</from-view-id>
     <navigation-case>
       <from-outcome>signup-success</from-outcome>
       <to-view-id>/signup-success.jsp</to-view-id>
     </navigation-case>
   </navigation-rule>
   <navigation-rule>
     <display-name>signup</display-name>
     <from-view-id>/signup.jsp</from-view-id>
     <navigation-case>
       <from-outcome>signup-failure</from-outcome>
       <to-view-id>/signup-failure.jsp</to-view-id>
     </navigation-case>
   </navigation-rule>

</faces-config>

這個文件的元素(見 表 2)比 web.xml 中的元素復雜一點兒,但是可以通過 Eclipse Web Tooling Platform 的圖形化編輯器創建其 中的大多數元素。

表 2. faces-config.xml 文件中的元素

元素 描述 <faces-config> JSF 應用程序數據的容器 <application> 允許指定應用程序設置、支持的語言等等 <managed-bean> 每個 <managed-bean> 標記定義和描述應用程序使用的一個托管 bean,包括在 JavaServer Pages(JSP)頁面中引用它 的名稱、實現這個 bean 的 Java 類的名稱以及 bean 的作用范圍。 <navigation-rule> 每個 <navigation-rule> 指定一個源頁面、一個響應字符串(這來自從源頁面調用的 bean 中的一個方法)以及與這個 響應對應的目標頁面。

我發現 <navigation-rule> 塊有點繁冗;我認為,應該允許每個 <navigation-rule> 中有多個 <navigation- case> 元素的,那會使代碼更清晰,但 JSF 不是我設計的。

devSignup geronimo-web.xml

geronimo-web.xml 文件相當簡單(見 清單 3),它表示在服務器上通過哪個 URL 顯露應用程序。

清單 3. Geronimo 將應用程序放在哪裡(geronimo-web.xml)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-1.1"
   xmlns:naming="http://geronimo.apache.org/xml/ns/naming">
   <context-root>/devSignup</context-root>
</web-app>

很簡單,不是嗎?

devSignup signup.jsp

在 清單 4 中可以看到,Developer Signup 輸入表單相當簡單,它只使用了文本輸入字段和一些基本的 Tomahawk 驗證器組件。

清單 4. Developer Signup 輸入表單

<?xml version="1.0" encoding="UTF-8" ?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0"
   xmlns:f="http://java.sun.com/jsf/core"
   xmlns:h="http://java.sun.com/jsf/html"
   xmlns:t="http://myfaces.apache.org/tomahawk">
   <jsp:output omit-xml-declaration="false" doctype-root-element="html"

  doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
     doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" />
   <jsp:directive.page contentType="text/html;charset=utf-8" />
   <f:view>
     <html xmlns="http://www.w3.org/1999/xhtml">
     <head>
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
     <title>Developer Forum Signup</title>
     </head>
     <body>
     <h1>Developer Forum Signup</h1>
     <p>Welcome to our forums! Please fill in the following form 
     to create your forum account.</p>

     <h:form>
       <dl>
         <dt>Screen name:</dt>
         <dd><h:inputText value="#{signupData.screenName}" /></dd>

         <dt>Email:</dt>
         <dd><h:inputText value="#{signupData.email}"
           id="email" required="true">
           <t:validateEmail />
         </h:inputText><br />
         <strong><h:message for="email" /></strong></dd>

         <dt>Password:</dt>
         <dd><h:inputSecret value="#{signupData.password}"
           id="password" required="true" /></dd>

         <dt>Password (for verification):</dt>
         <dd><h:inputSecret id="password_verify"
           required="true">
           <t:validateEqual for="password" />
         </h:inputSecret><br />
         <strong><h:message for="password_verify" /></strong></dd>

         <dt>Birthday:</dt>
         <dd><t:inputDate id="birthday"
           value="#{signupData.birthday}" popupCalendar="true" /></dd>
       </dl>

       <h:commandButton action="#{signupData.register}">Sign up</h:commandButton>
     </h:form>
     </body>
     </html>
   </f:view>
</jsp:root>

這與本系列 第 2 部分 中的 signup.jsp 稍有差異;這個版本使用 XML 語法而不是 JSP 語法。(我喜歡格式良好的 XML!)

devSignup SignupData.java

最後是這個應用程序中使用的托管 bean 的源代碼(見 清單 5)。

清單 5. Developer Signup 應用程序的托管 bean

package devSignup;

public class SignupData {
   // Properties and accessors.
   private String _screenName = "nobody";

   private String _email = "[email protected]";

   private String _password = "";

   private java.util.Date _birthday = null;

   public SignupData() {
     this._birthday = new java.util.Date();
   }

   public java.util.Date getBirthday() {
     return this._birthday;
   }

   public void setBirthday(java.util.Date newBirthday) {
     this._birthday = newBirthday;
   }

   public String getScreenName() {
     return this._screenName;
   }

   public void setScreenName(String newScreenName) {
     this._screenName = newScreenName;
   }

   public String getEmail() {
     return this._email;
   }

   public void setEmail(String newEmail) {
     this._email = newEmail;
   }

   // NOTE: THIS IS NOT SECURE, DON'T DO THIS
   // WITH YOUR PASSWORDS!
   public String getPassword() {
     return this._password;
   }

   public void setPassword(String newPassword) {
     this._password = newPassword;
   }

   // The registration attempt handler.
   public String register() {
     if ((this._email == null) || (this._screenName == null)
         || (this._password == null)) {
       // Bad code? lost data? 
       return "signup-failure";
     }

     if ((this._email.trim().length() < 3)
         || (this._email.indexOf("@") == -1)) {
       // Bad email address.
       return "signup-failure";
     }

     if (this._password.trim().length() < 8) {
       // Password too short.
       return "signup-failure";
     }

     return "signup-success";
   }

} 

這個簡單的 bean 管理從表單收集的所有數據。它還提供一個方法 register(),當用戶點擊 Sign up 按鈕時從表單調用這個方法。它 返回前面在 faces-config.xml 文件中看到響應字符串之一。JSF 引擎使用這些響應字符串判斷接下來要顯示哪個頁面。

既然已經回顧了 Developer Signup 應用程序的 MyFaces 版本,下面就討論如何添加 Spring 功能。

在 devSignup 中添加 Spring MVC

現在 devSignup 已經准備好添加 Spring MVC 功能了,我們馬上開始。

開始

在 Eclipse 的 Navigator 視圖中右擊 devSignup 項目,然後從上下文菜單中選擇 Properties。Eclipse 顯示 Properties 對話框。

點擊列表中的 JSF Library References 顯示 JSF Library References 面板(見 圖 3)。

圖 3. 在 devSignup 項目中添加 Spring

點擊選擇列表區域中的 New 按鈕(不是 Implementation Library 下拉列表旁邊的按鈕),顯示 Create JSF Library 對話框。使用這 個對話框定義 JSF 組件庫,這樣就可以在項目中包含它。這非常適合添加那些包含幾個 JAR 的組件庫或依賴於其他項目的 .jar 文件的組 件庫。

在 Library Name 字段中輸入庫名(我使用 Spring Framework),然後從 Version Supported 下拉菜單中選擇 v1_1,因為 MyFaces 實現了 1.1 版的 JSF 規范。

點擊 Add 按鈕,然後選擇 Spring .jar 文件:spring.jar(見 圖 4)。

圖 4. 建立 Spring Framework 庫引用

這樣就行了。Spring Framework 還附帶了其他 JAR 文件;spring.jar 包含其中所有內容。如果您希望以更細的粒度控制應用程序的內 容,或者希望節省服務器上的空間,那麼可以在這些文件中進行選擇。Spring 發行版附帶的 readme.txt 文件中提供了每個 JAR 文件的依 賴項的完整清單。還有另一個文件(spring-mock.jar),其中包含模擬服務器上下文和幫助進行單元測試的其他類:

spring-core.jar —— 核心實用程序;所有代碼都需要這個文件

spring-beans.jar —— JavaBeans 支持,bean 容器

spring-aop.jar —— AOP 框架,源代碼級元數據支持,AOP Alliance 接口

spring-context.jar —— 應用程序上下文,驗證,Java Naming and Directory Interface(JNDI),UI 上下文支持

spring-dao.jar —— Data Access Objects(DAO)支持,事務處理基礎設施

spring-jdbc.jar —— JDBC 支持

spring-support.jar —— Java Management Extensions(JMX)支持,J2EE Connector Architecture(JCA)支持,調度支持,郵件支 持,緩存支持

spring-web.jar —— Web 應用程序上下文,多部分解析器,Struts 支持,JSF 支持,Web 實用程序

spring-webmvc.jar —— Framework servlet,Web MVC 框架,Web 控制器,Web 視圖

spring-remoting.jar —— Remoting 支持,Enterprise JavaBeans(EJB)支持,Java Message Service(JMS)支持

spring-orm.jar —— iBATIS SQL Maps 支持,Apache Object Relational Bridge(OJB)支持,TopLink 支持,JDO 支持

spring-hibernate.jar —— Hibernate 2.1 支持,Hibernate 3.0 和更高版本支持

點擊 Finish(見 圖 4)將新的 Spring Framework 庫添加到項目屬性的 JSF Library References 面板中的列表中。這個新的 Spring Framework 庫添加到右邊的列表中,它會自動地包含在項目的 .war 文件中。

點擊 OK 應用修改並關閉項目屬性對話框。

任務列表

為了啟用 Spring Framework,需要將以下東西添加到應用程序中:

將一個新的 <listener> 添加到 web.xml 中

將一個新的 <variable-resolver> 添加到 faces-config.xml 中

將一個新的托管屬性添加到 bean 中;這指定如何將 Spring bean 注入現有的應用程序

applicationContext.xml 文件,它定義應用程序的 bean(包括現有的 JSF bean)

SignupData bean 的一個新屬性

一個新的基於 Spring 的 bean

一些表明新的 Spring bean 正在工作的內容

我們開始吧!

添加 <listener>

將 清單 6 中的代碼添加到 web.xml 中,放在現有的 <listener> 元素前面,作為 <web-app> 元素的子元素,而不是任 何其他 web.xml 標記的子元素。

清單 6. 在 web.xml 中啟用 Spring Framework

<listener>

<listener-class>org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

<listener> 元素將 Spring 的 ContextLoaderListener 添加到應用程序中;它啟動 Spring 的根 WebApplicationContext,從 而處理在啟動應用程序時需要的其他 Spring 部分的創建和配置。

添加 Spring 變量解析器

保存 web.xml 文件,並右擊 faces-config.xml 文件。

從上下文菜單中選擇 Open With > XML Editor,從而編輯這個文件,讓應用程序使用 Spring 變量解析器之一。

將 清單 7 中的代碼行添加到 faces-config.xml 中的 <application> 元素中。

清單 7. 在 faces-config.xml 文件中指定使用 Spring 變量解析器

<variable-resolver>org.springframework.web.jsf.DelegatingVariableResolv
er</variable-resolver>

DelegatingVariableResolver 將查找應用程序使用的任何 bean 名稱或 bean 屬性引用。如果它無法解析對 Spring bean 或屬性的引 用,就會將查找委托給標准的 JSF 變量解析器。

將一個新的托管屬性添加到 bean 中

要把一個新屬性添加到這個文件中聲明的 signupData bean 中;hash 屬性將由 Spring bean 管理,用來演示將 Spring 注入現有應用 程序的技術。

將 清單 8 中的代碼添加到 faces-config.xml 中定義 signupData bean 的 <managed-bean> 塊裡面。

清單 8. 將一個托管屬性添加到現有的 bean 中

<managed-property>
   <property-name>hash</property-name>
   <value>#{genHash.hash}</value>
</managed-property>

這會創建一個新的 hash 托管屬性,它映射到稍後定義的 genHash bean 的 hash 屬性。

添加 applicationContext.xml 文件

保存 faces-config.xml 文件。

右擊 devSignup 項目的 WEB-INF 文件夾,然後從上下文菜單中選擇 New > File。

輸入 applicationContext.xml 作為文件名,然後將 清單 9 中的代碼添加到新文件中。

清單 9. 定義 Spring 管理的 bean

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
   "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
   <bean id="signupData" class="devSignup.SignupData"
lazy-init="true"/>
   <bean id="genHash" class="devSignup.HashGenerator"
lazy-init="true"/>
</beans>

這些是 Spring 將知道的 bean,所以在這裡也會找到 JSF bean,signupData。Spring 的 bean 工廠會在需要時創建和管理這些 bean 。如果保持 lazy-init 屬性為默認值(false),這些 bean 就會在應用程序啟動時創建。如果將 lazy-init 設置為 true,bean 就會在 需要它們時創建。

基於 Spring 的 bean

將 清單 10 中的 Java 代碼添加到 devSignup 文件夾中的 SignupData.java 中;這會添加 hash 屬性及其訪問器。

因為這是一個托管屬性,它引用另一個 bean 中的一個屬性,所以 Spring 在內部使用它引用另一個 bean 中的屬性。JSF 應用程序實 際上不使用它,因為 Spring 的 DelegatingVariableResolver 會截取對它的任何引用。

清單 10. 將 hash 屬性添加到 SignupData.java 中

private String _hash = null;

public SignupData() {
   this._birthday = new java.util.Date();
}

public String getHash() {
   return this._hash;
}

public void setHash( String newHash ) {
   this._hash = newHash;
} 

還需要在 devSignup 包中創建一個新的 Java 類,HashGenerator。

右擊 devSignup 項目中的 src 文件夾,然後從上下文菜單中選擇 New > Other。

在這個向導中,選擇 Class,然後點擊 Next 創建一個新的 Java 類。

將包設置為 devSignup(或者點擊 Package 字段旁邊的 Browse 按鈕並選擇 devSignup),將名稱設置為 HashGenerator。

點擊 Finish 創建新類,並按照 清單 11 中的代碼編輯它的源代碼。

清單 11. 新的 HashGenerator 類

package devSignup;

import javax.faces.context.FacesContext;

import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.web.jsf.FacesContextUtils;

public class HashGenerator {
   public void setHash( String newHash ) {
     // Do nothing, this is a read-only bean.
     return;
   }

   public String getHash() {
     ApplicationContext ctx = FacesContextUtils.getWebApplicationContext( 
         FacesContext.getCurrentInstance());

     try {
       SignupData myBean = (SignupData)ctx.getBean("signupData" );

       return Integer.toString( myBean.getScreenName().hashCode() );
     } catch( NoSuchBeanDefinitionException ex ) {
       return "no-data-bean";
     } catch( javax.faces.FacesException ex ) {
       return "no-screen-name";
     }
   }
} 

這個 HashGenerator bean 有一個只讀屬性:hash。嘗試設置這個屬性不會產生任何效果;應該選擇將其記入日志,或者利用它來建立 更強大的 hash 生成方法。在 getHash() 方法中提供了您看到的第一段 Spring Java 代碼。

在 getHash() 方法中,使用 Spring 的 FacesContextUtils.getWebApplicationContext() 方法創建一個 ApplicationContext 對象, 然後就可以使用這個對象查找在應用程序中運行的特定 bean 實例。在這裡,使用它尋找 signupData bean,以便可以通過 Java String 對象的 hashCode() 方法提供它的 screenName 屬性。如果無法找到這個 bean,或者請求了一個無效的屬性,就會引發異常,這裡的 try/catch 塊捕捉並處理這些異常。

這就是所有代碼。現在,當構建並部署這個應用程序之後,bean 將在 Spring 中運行,還會運行 Spring 提供的所有其他東西。更復雜 的應用程序可以相當輕松地利用這些特性;例如,可以使用 Spring 對 Hibernate(一種對象/關系持久化和查詢服務)的支持來存儲和檢 索用戶數據,並提供一種將現有用戶登錄進開發人員論壇的方法。

基於 Spring 的新 bean 的運行效果

應該做的最後一件事是,在應用程序中添加一些東西,以便能夠看到這個新的 HashGenerator bean 的運行效果。

在 Eclipse 中打開 signup-success.jsp 文件。您可能還記得,當用戶成功地通過注冊頁面時,就會顯示這個頁面。修改 <p> 元素中的內容,讓它顯示用戶新的屏幕名以及計算出的 hash 值。

將當前的 <p>...</p> 元素替換為 清單 12 的內容。

清單 12. 顯示您的勞動成果

<p>
Your application was successful, ${signupData.screenName}, welcome to our
forums!
Your hash is ${signupData.hash}.
</p>

現在,頁面上不再顯示一般化的歡迎消息,而是用個性化的消息歡迎用戶,他們會看到直接來自 signupData bean 的名稱以及來自 signupData 的 hash 屬性引用的 HashGenerator bean 的 hash 值。這個頁面看起來像 圖 5 這樣。

圖 5. 現在,用一個更加個性化的消息向用戶祝賀成功

因為已經修改完 Developer Forum Signup 應用程序,現在需要將它部署到 Geronimo 上。

部署新的 Developer Signup 應用程序

現在,是時候看看 Developer Signup 應用程序的工作效果了。需要構建這個項目、導出 .war 文件並將它部署到 Geronimo 服務器上 。

在 Eclipse 的 Navigator 視圖中點擊 devSignup 項目,然後從菜單中選擇 Project > Build Project。Eclipse 編譯 Java 代碼 並驗證 JSP 頁面和 XML 文件。

在 Navigator 視圖中右擊 devSignup,然後從上下文菜單中選擇 Export。

在 Export 向導中,展開 Web 組,選擇 WAR file,然後點擊 Next 顯示 WAR Export 面板,見 圖 6。

圖 6. 導出 .war 文件

點擊 Browse 按鈕,選擇一個目標目錄和 .war 文件的文件名(我將自己的文件作為 devSignup.war 保存到桌面,這樣在服務器上部署 它時就很容易找到它。)

點擊 Finish,導出 .war 文件。

打開您喜歡的 Web 浏覽器,並訪問 http://localhost:8080/console/(如果您的 Geronimo 服務器不在同一台機器上運行,那麼要用 它的主機名替換 localhost)。這會顯示 Geronimo 管理控制台登錄屏幕。

登錄管理控制台(記住,默認用戶名是 server,默認密碼是 manager,應該修改它們。)

如果在服務器上已經運行著 devSignup(因為您已經按照前面的教程進行了實踐),那麼點擊屏幕左邊列表中的 Applications 部分中 的 Web App WARs 項。這會列出已經安裝的所有 Web 應用程序,每個應用程序旁邊有一個 Uninstall 鏈接。在部署新版本之前應該先卸載 devSignup。

點擊 Console Navigation 列表中 Applications 部分中的 Deploy New,顯示 Install New Applications 屏幕。

點擊 Archive 字段旁邊的 Browse 按鈕,找到剛才創建的 .war 文件。

因為已經選中了 Start app after install,點擊 Install,上傳 .war 文件並啟動應用程序。在浏覽器完成存檔文件的上傳而且 Geronimo 啟動了應用程序之後,會看到一個成功消息。

這樣就完成了,您已經用強大的 Spring Framework 成功地擴展了 Developer Signup Web 應用程序!

結束語

本教程簡要介紹了 Spring Framework,並討論了如何將它添加到一個現有的 JSF 應用程序中,即在 第一篇教程 中開始開發的 Developer Forum Signup 示例應用程序。

在這個系列中,您了解了 Apache MyFaces 以及可以用來擴展 JSF Web 應用程序的幾種技術和框架,還了解了如何使用 Eclipse IDE 的 Web Tools Platform 簡化 JSF 應用程序的開發。我希望這個系列能夠對您有所幫助!

原文地址:http://www.ibm.com/developerworks/cn/edu/os-dw-os-ag-jsf5.html

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved