軟體專案實訓及課程設計指導——如何在Web應用系統中實現Velocity 模板引擎與Struts 框架相互整合的應用例項
1、Velocity Tools 子專案及其中的 VelocityStruts 元件
(1)Velocity Tools是什麼
J2EE Web應用系統的設計和開發人員透過應用Velocity Tools中相關的元件,不僅可以將Velocity 模板引擎應用於普通的J2EE Web應用系統環境中,也還可以與J2EE系統平臺中的各種應用框架相互整合,從而也允許將Velocity 模板引擎應用於如Struts和Struts2、Spring等應用框架的環境中。
(2)VelocityStruts 元件
Velocity Tools 子專案中的 VelocityStruts 元件包含整合 Velocity 模板引擎與 Struts 應用框架的所有功能。VelocityStruts 提供了一組專用的 Velocity 模板引擎工具,用於訪問 Struts應用框架中專有的資源和 Velocity 模板檔案中的資訊。其主要的目的就是結合Velocity模板引擎在MVC體系架構的應用系統中的檢視層上的優勢跟Struts應用框架在MVC體系架構的應用系統中的控制層上的優勢。
VelocityStruts元件會在Struts應用框架的Action元件類返回某個actionForward目標物件之後,自動地檢測返回的目標資源的型別——如果發現是一個*.jsp頁面檔案,則它自動呼叫JSP解析器Jasper並按照傳統的JSP頁面流程執行,而如果一旦發現它返回的目標資源是一個Velocity 模板引擎的模板*.vm檔案,則會自動地呼叫Velocity模板引擎中的模板解析引擎對其進行處理——也就是讓Struts應用框架的forward 最終轉向某個*.vm檔案。
2、VelocityStruts系統包檔案和用於 VelocityStruts 整合的各種工具
由於在Velocity模板引擎系統中沒有提供類似於Struts應用框架標籤庫中的各個功能標籤,而替代的方式是採用toolbox.xml定義檔案自定義工具類,這些工具類可以直接在Velocity模板引擎的模板頁面中使用——因為這些工具類和Struts 應用框架標籤的功能類似,但在使用規則上要比Struts應用框架的標籤更容易和更靈活。
下圖所示為下載的velocity-tools-1.4.zip工具包檔案中所包含的各個工具類所在的JAR包檔案,主要為三個檔案:velocity-tools-generic-1.4.jar、velocity-tools-1.4.jar和velocity-tools-view-1.4.jar。在將Velocity 與Struts 應用框架相互整合時,應該要將它們加入到Web系統的WEB-INF/lib目錄中。
下表所示為Velocity Tools 子專案中的主要的工具類的功能說明,這些工具不僅保留了Struts 框架標籤的方便特性,而且還具有Velocity模板引擎的靈活性。從而可以在模板頁面中達到與採用Struts框架標籤庫的標籤相同的應用功能效果。
3、VelocityStruts工具箱配置檔案toolbox.xml
J2EE Web應用系統的開發人員可以在VelocityStruts工具箱配置檔案toolbox.xml中定義在Web專案中所需要的與Velocity模板引擎配合使用的各種實用工具類,在Velocity 模板引擎系統中提供了許多預先構建好的工具、並且還建立了許多Struts 應用相關的工具來模擬Struts框架中的標籤功能。
如下程式碼示例中的示例為某專案中定義的toolbox.xml檔案中的示例內容,並且該檔案放在WEB-INF檔案目錄中。這些工具類的主要功能請讀者參考上面表中的功能說明,Web應用系統的開發人員可以根據Web專案中的需要有選擇地定義有關的工具類——某Web專案中定義的toolbox.xml檔案中的示例內容
<?xml version="1.0"?><toolbox> <tool> <key>link</key> <scope>request</scope> <class>org.apache.velocity.tools.struts.StrutsLinkTool</class> </tool> <tool> <key>msg</key> <scope>request</scope> <class>org.apache.velocity.tools.struts.MessageTool</class> </tool> <tool> <key>errors</key> <scope>request</scope> <class>org.apache.velocity.tools.struts.ErrorsTool</class> </tool> <tool> <key>form</key> <scope>request</scope> <class>org.apache.velocity.tools.struts.FormTool</class> </tool> <tool> <key>tiles</key> <scope>request</scope> <class>org.apache.velocity.tools.struts.TilesTool</class> </tool> <tool> <key>validator</key> <scope>request</scope> <class>org.apache.velocity.tools.struts.ValidatorTool</class> </tool></toolbox>
4、在web.xml 檔案中配置 VelocityViewServlet元件以處理模板檔案
由於VelocityStruts是透過一個名為VelocityViewServlet的Servlet元件實現將所有的請求以*.vm為結尾的資源都轉交給這個Servlet元件去處理。因此,需要在Web專案的部署描述符web.xml 檔案中配置定義出VelocityViewServlet 以處理專案中的各種*.vm 檔案、並且告訴 VelocityViewServlet在哪裡可以找到toolbox.xml的定義配置檔案——請見下面的程式碼示例中所示的在web.xml檔案中對VelocityViewServlet的配置定義內容示例——在web.xml檔案中對VelocityViewServlet的配置定義內容示例
<servlet> <servlet-name>velocity</servlet-name> <servlet-class>org.apache.velocity.tools.view.servlet.VelocityViewServlet</servlet-class> <init-param> <param-name>org.apache.velocity.toolbox</param-name> <param-value>/WEB-INF/toolbox.xml</param-value> </init-param> <init-param> <param-name>org.apache.velocity.properties</param-name> <param-value>/WEB-INF/velocity.properties</param-value> </init-param> <load-on-startup>10</load-on-startup></servlet><servlet-mapping> <servlet-name>velocity</servlet-name> <url-pattern>*.vm</url-pattern></servlet-mapping>
該VelocityViewServlet的一個初始化引數"org.apache.velocity.toolbox"的含義是在系統中引入了一個工具箱配置檔案toolbox.xml,而另一個初始化引數org.apache.velocity.properties定義了Velocity的屬性配置檔案的位置,這個velocity.properties屬性檔案定義了Velocity的一些配置資訊——讀者可以參考前面的程式碼示例中的velocity.properties屬性配置檔案的示例。
透過對VelocityViewServlet的配置定義達到把以 *.vm 結尾的檔案傳送給 VelocityViewServlet,而VelocityViewServlet把Velocity模板引擎的命令處理結果表示成HTML響應輸出。
VelocityViewServlet元件提供了對請求物件和屬性、會話物件和屬性以及 Servlet 上下文和屬性的直接訪問。但在應用它時,Web應用系統的開發人員要保證在WEB-INF/lib目錄下必須要有Velocity模板引擎的velocity-tools-view-1.4.jar系統包檔案(請見前面示圖中所示系統包目錄及檔案截圖)。
5、程式設計Action類和在struts-config.xml配置檔案中定義Action類
(1)程式設計實現特定功能的Action類程式
package com.px1987.velocitystrutsweb.action;import org.apache.struts.validator.*;import org.apache.struts.action.*;import javax.servlet.http.*;public class UserLoginAction extends Action { public ActionForward execute(ActionMapping actionMapping, ActionForm actionForm, HttpServletRequest request, HttpServletResponse response) { DynaValidatorForm dynaValidatorForm = (DynaValidatorForm) actionForm; String userName = (String) dynaValidatorForm.get("userName"); String userPassWord = (String) dynaValidatorForm.get("userPassWord"); boolean okOrNot=userName.equals("yang")&&userPassWord.equals("1234"); if(okOrNot){ UserInfo oneUserInfo=new UserInfo(); oneUserInfo.setUserName(userName); oneUserInfo.setUserPassWord(userPassWord); request.setAttribute("oneUserInfo", oneUserInfo); return actionMapping.findForward("loginSuccess") ; } else{ ActionErrors errors = new ActionErrors(); errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("login.failure")); saveErrors(request, errors); return actionMapping.findForward("loginFailure") ; } }}
(2)在struts-config.xml配置檔案中定義該Action類及其<forward>的配置
根據Struts應用框架的要求,需要對上面程式碼示例中的UserLoginAction類在struts-config.xml配置檔案中定義該Action類及其<forward>的配置。
下面的程式碼示例為UserLoginAction類的定義內容示例,其中定義了名稱為loginSuccess的目標資原始檔為/userManager/LoginSuccess.vm,而名稱為loginFailure的目標資原始檔為/userLogin.vm——在struts-config.xml檔案中定義UserLoginAction類及其<forward>的配置。
<action input="/userLogin.vm" name="userLoginForm" path="/doUserLogin"scope="request" validate="false"type=" com.px1987.velocitystrutsweb.action.UserLoginAction" > <forward name="loginSuccess" path="/userManager/LoginSuccess.vm"/> <forward name="loginFailure" path="/userLogin.vm"/></action>
6、在Web專案中設計和開發實現Velocity 模板檔案
(1)userLogin.vm模板檔案的內容
userLogin.vm模板檔案一方面作為使用者登陸請求的功能頁面,另一方面也作為登陸失敗時的錯誤資訊顯示的功能頁面,並且在該Velocity 模板檔案的頁面中利用VelocityStruts的工具類動態地獲得所需要的資料——請參考如下程式碼示例中的Velocity 模板檔案的示例—— 實現使用者登陸功能的Velocity 模板檔案userLogin.vm的示例,並請注意其中黑體所標識的程式碼語句。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"><html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> <title>使用者登入請求功能頁面</title> </head> <body> <form method="POST" action="$link.setAction('/doUserLogin')"> 請輸入使用者名稱稱:<input type="text" name="userName"><br> 請輸入使用者密碼:<input type="password" name="userPassWord"><br> <input type="submit" value="提交" name="submit"> <input type="reset" value="重來" name="reset"> #if ($errors.exist()) <ul> #foreach ($oneError in $errors.all) <li>$oneError</li> #end </ul> #end </form> </body></html>
在userLogin.vm 模板檔案中採用$!errors.all 得到錯誤訊息佇列中的所有的錯誤訊息,而採用$link.setAction('/doUserLogin ') 獲得UserLoginAction類轉發的 URL。
由於Velocity模板引擎系統採用簡單而強大的模板語言VTL實現對Web頁面的渲染,因此能保證在Dreamwaver之類的Web頁面視覺化編輯器中都能夠正常顯示(參看如下示例圖所示)。
另外,模板檔案可以是任意的副檔名,採用*.vm、*.html或者*.xml都是可以的(本示例採用*.vm副檔名),這樣就能直接在Web瀏覽器中看到Web頁面的預覽的效果。
(2)LoginSuccess.vm模板檔案的內容
該LoginSuccess.vm模板檔案作為使用者登陸成功後的資訊顯示頁面,並且在該模板檔案中動態地獲得由前面程式碼示例中的UserLoginAction類轉發來的引數——請參考如下的程式碼示例中的Velocity 模板檔案的示例——使用者登陸成功後的資訊顯示頁面LoginSuccess.vm模板檔案的內容,並請注意其中黑體所標識的程式碼語句。