前面的《Velocity之Web篇》講述了Velocity的Web應用基礎,主要以Velocity+Servlet爲主講述基本Web開發模式,但畢竟這只是基礎篇,如果Velocity與目前應用較廣的Web框架結合起來,那麼將能達到一步千里的目的,下面我們就結合Struts來舉例兩者是怎樣進行整合工作的。
我們需要的運行資源爲:Tomcat(我用5.5版本)、jakarta-struts-1.2.4.zip(從http://struts.apache.org/download.cgi上下載)。
Velocity推出後,已經陸續推出了不少Velocity tools,發展爲一系列的子項目,其中包含VelocityStruts,它是以Struts爲基本框架,但以Velocity爲模版引擎代替View層來開發Web應用的,它的核心是VelocityViewServlet類和其他一些附屬工具包,來帶動Velocity和Struts的整合。
對VelocityStruts最好的解釋還是來看下圖,引自VelocityStruts的docs,
根據上圖可以看到其實VelocityStruts的前面(左邊)部分還是完全是Struts的模式,而在Forward轉向的時候就增多了對Velocity Template Language編寫的模版的支持,使原來轉向Jsp View層可以轉向VTL View層。
我們看具體的例子,首先編輯一個簡單的Struts Action,在它內部進行商業邏輯處理後得到的展示數據,然後Forward到一個.vm 的View中,代碼如下:
package com.javayou.velocity.struts;
import javax.servlet.http.*;
import org.apache.struts.action.*;
import java.util.*;
/*
* @author Liang.xf 2004-12-20
* VelocityStruts 演示
* www.javayou.com
*/
public class VelocityAction extends Action {
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
System.out.println(" --- VelocityAction working ---");
//待展示的列表數據
String p1 = "1, LiuDong";
String p2 = "2, Liang.xf";
Vector personList = new Vector();
personList.addElement(new String(p1.getBytes(), "ISO-8859-1") );
personList.addElement(new String(p2.getBytes(), "ISO-8859-1") );
//設置數據
HttpSession session = request.getSession() ;
session.setAttribute("theList", personList);
return mapping.findForward("welcome");
}
}
編譯只需要 struts.jar 和 j2ee.jar 兩個jar包,假設和源文件一起放置在本地目錄下,編譯命令如下:
javac -classpath ./struts.jar;./j2ee.jar VelocityAction.java
這樣,加上sample.vm,即完成資源的預備,sample.vm 參考《Velocity之Web篇》。
因爲不想在搭建Struts環境上在此多言,故我們藉助Struts的樣例進行快速搭建,在資源預備中得到的jakarta-struts-1.2.4.zip,解壓後,得到一個jakarta-struts-1.2.4文件,更名爲jakarta-struts-1.2.4.zip,再繼續解壓,得到Struts1.2.4,再其webapps目錄下,把struts-examples.war Copy到Tomcat的webapps目錄下,首先啓動Tomcat,Tomcat運行後自動解壓和發佈struts-examples.war。
以上環境搭建好後,就可以看看Velocity是如何整合到上述的Struts環境下了,首先更改struts-examples/WEB-INFO/下的web.xml,增加Velocity對.vm的處理:
<servlet>
<servlet-name>velocityEngine</servlet-name>
<servlet-class>
org.apache.velocity.tools.view.servlet.VelocityViewServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>velocityEngine</servlet-name>
<url-pattern>*.vm</url-pattern>
</servlet-mapping>
以上是註冊了Servlet:velocityEngine,並用來處理 *.vm。
然後我們需要更改/WEB-INFO下的struts-conf.xml,在action-mappings裏增加action:
<action path="/sample"
type="com.javayou.velocity.struts.VelocityAction"
scope="request">
<forward name="welcome" path="/WEB-INF/vm/sample.vm"/>
</action>
接下來需要把編譯好的VelocityAction.class Copy到struts-examples/WEB-INFO/classes/下的com/javayou/velocity/struts包內,把sample.vm增加到struts-examples/WEB-INFO/vm目錄內,以上沒有的目錄需要手工創建好。
至此環境全部佈置完畢,重啓Tomcat,可以在IE裏輸入:http://localhost:8080/struts-examples/sample.do,即可得到最後結果。
以上可以看到對原來Struts最大的改變就是在Action處理後的Forward更改上,原來是直接Forward到新的.do 或 Jsp頁面上,而在這裏變成了 .vm,而.vm在web.xml中已經被註冊由VelocityViewServlet進行處理,這樣,Struts的最後流向就被轉向了Velocity上。
最後再來提一個問題,有人可能有疑問,Struts提供了Taglib的自定義開發,以支持靈活的頁面展示腳本,而Velocity提供的相關替代是宏,宏的編寫默認在VM_global_library.vm文件內,具體文件名在velocity.properties中指定,簡單舉例如下:
# macro (printList)
# if ($theList)
# foreach ($ elem in $theList)
$ elem
#end
# end
# end
#macro( poundthis $truth )
#if ($truth )
<td align=center class=v10><b>#</b></td>
<td align=center class=v10><b> # </b></td>
<td align=center class=v10><b>/#</b></td>
#end
#end
這樣在.vm中就可以使用printList和poundthis這兩個標記了。