第1.8式. 使用XDoclet 產生Struts配置文件
問題
當你修改或者新建一個Action 或ActionForm時,你需要修改對應的Struts 配置文件。
動作要領
使用XDoclet 工具,配合Ant,來處理Java代碼中可以自動產生truts-config.xml文件的注解。
動作變化
現在的大多數應用軟件系統都有可執行代碼文件文本配置文件組成。這種方式可以使你更容易的在各種不同的環境之間移植,并且減少必須針對各種不同部署而修改的代碼量。但是它帶來了另外一個負擔,那就是保持代碼和配置文件之間的一致性。
XDoclet 工具,原本開發來是針對EJB的開發,它就可以解決這個問題。通過XDoclet,開發者能夠在代碼中放置能夠描述與代碼相關的配置屬性的注解,這些注解非常類似于JavaDoc 標簽。在構建時,你可以使用定制的Ant 任務,由它來使用XDoclet 從而處理這些標簽并產生對應的XML 配置文件。
對Struts來說,XDoclet 可以產生struts-config.xml文件中的下列元素:
另外, XDoclet 還可以創建字段級的Struts Validator 配置,通常是位于validation.xml 文件之中。最后,如果你要映射EJB 實體Bean的屬性到Struts ActionForms, XDoclet 可以不產生ActionForm 的Java 源代碼。
首先,你需要添加一個任務到你的Ant 的build 腳本文件中,該任務可稱為XDoclet 任務。Example 1-9展示了一個為struts-example 應用產生struts-config.xml 文件的Ant任務。
Example 1-9. Webdoclet Ant target
<target name="webdoclet" depends="init">
<taskdef
name="webdoclet"
classname="xdoclet.modules.web.WebDocletTask"
classpathref="project.class.path"/>
<webdoclet
mergedir="${merge.dir}"
destdir="${generated.xml.dir}"
excludedtags="@version,@author"
force="${xdoclet.force}">
<fileset dir="${src.dir}">
<exclude name="**/*Registration*.java"/>
<include name="**/*.java"/>
</fileset>
<strutsconfigxml
version="1.1"/>
</webdoclet>
</target>

這個目標(target)調用webdoclet 定制Ant任務,它是由XDoclet提供的。此任務可以產生多個Web應用相關的工件,包括 web.xml 文件, struts-config.xml 文件,validation.xml 文件。對Struts 應用來說,你可能不需要產生web.xml 文件;因為對Struts 應用,該文件并不經常改變。在Example 1-9中,webdoclet 任務被用于產生struts-config.xml 文件。
并不是所有的struts-config.xml 文件中的元素都可以或者應該從注解的代碼中產生。像全局forward, 全局例外處理,消息資源,插件等都并不和特定的Action 或ActionForm 類相關。
XDoclet 是通過讓你在位于特定的目錄中的文件中放置靜態配置來處理這些事情的。在構建時, XDoclet 將這些文件中代碼中產生的元素進行合并。你可以通過mergedir 屬性來指定這些靜態文件的位置。destdir 屬性則指定將創建的文件的存放目錄。通常,你需要為這些產生的文件創建一個單獨的目錄,然后在其成功創建后將它們拷貝到適當的目錄中一共打包或者部署。excludedtags 屬性指定排除在XDoclet 處理之外的JavaDoc 標簽。
|
執行@author和 @version標簽是通用的。 |
最后, force 屬性強制XDoclet 產生一個新的配置文件。如果這個屬性為false, 新文件只有在對應的注解Java代碼發生改變時才會產生。
fileset 元素告訴XDoclet 要處理哪些Java 源文件。你可以使用該元素來指示那個源文件包含XDoclet 注解。例如,struts-example 應用使用了兩個Struts 配置文件:struts-config.xml 和 struts-config-registration.xml。如Example 1-9所示,你可以通過設置fileset元素來排除包含名稱"Registration"的類從而排除放入struts-config-registration.xml 文件中的元素。
strutsconfigxml 元素指示XDoclet 產生struts-config.xml 文件。XDoclet 默認情況下將產生Struts 1.0兼容的配置文件。因此,如果你用Struts1.1你必須指定版本為"1.1"。XDoclet 也使用該屬性提供對Struts 1.2 的支持。
一旦你在構建文件中創建了這個target,你就可以添加注解到Action 和ActionForm 類的代碼中。對ActionForm, XDoclet 提供了@struts.form 標簽來產生form-bean 元素。下面的代碼展示了如何在struts-example 應用的SubscriptionForm中使用這個類一級的標簽:

/**//**
* 用于用戶概要頁面的
*
* @struts.form
* name="subscriptionForm"
*/


public final class SubscriptionForm extends ActionForm
{

}

在webdoclet target 被執行時,將在struts-config.xml 中產生下面的form-beans 元素:
<!-- ========== Form Bean Definitions =================================== -->
<form-beans>
<form-bean
name="subscriptionForm"
type="org.apache.struts.webapp.example.SubscriptionForm"
/>

<!--
If you have non XDoclet forms, define them in a file called
struts-forms.xml and place it in your merge directory.
-->
</form-beans>

XDoclet 使用你在標簽中指定的名稱來產生form-bean 元素,并且使用ActionForm 的權限定類名來創建type 屬性。這一特征也是XDoclet最大的優點之一。你的類的屬性,比如類名、包名、方法名等,對XDoclet 都可使用,就像它們被用于產生Javadocs 一樣。XDoclet 將在產生的文件的適當位置使用這些值。
|
如果你修改了一個類的類名或者包名, XDoclet將產生正確的配置元素而不會混淆。雖然IDE 的重構工具也可以處理這種類型的改變,但是使用XDoclet這是另外一種可以集成到現有的Ant構建過程中的解決方案。 |
你可以使用XDoclet 來從Action類中產生action 元素。XDoclet 使用@struts.action 標簽來指定action 元素。另外,@struts.action-forward 標簽則可以指定嵌套的forward 元素。同時@struts.action-exception標簽可以用于產生action特定的宣稱性例外處理。struts-example 中的LoginAction.java 類示于下方,其中還包括產生完整的action元素所需的注解:

/**//**
* Implementation of <strong>Action</strong> that validates a user logon.
*
* @struts.action
* path="/logon"
* name="logonForm"
* scope="session"
* input="logon"
*
* @struts.action-exception
* key="expired.password"
* type="org.apache.struts.webapp.example.ExpiredPasswordException"
* path="/changePassword.jsp"
*/

public final class LogonAction extends Action
{

}

標簽中的語法必須嚴格匹配對應的XML元素的語法。如果你已經有定義了的 struts-config.xml 文件,一個好辦法是將struts-config.xml中的XML元素剪切粘貼到Action 類中。使 XDoclet 能夠認可這些標簽作必要的修改。下面位于LogoffAction.java 文件中的注解展示了如何使用@struts.action-forward 標簽:

/**//**
* Implementation of <strong>Action</strong> that processes a
* user logoff.
*
* @struts.action
* path="/logoff"
*
* @struts.action-forward
* name="success"
* path="/index.jsp"
*/


public final class LogoffAction extends Action
{

}


雖然XDoclet 對產生struts-config.xml 文件大有幫助,它也并不是萬能的。某些action 元素并不與任何你創建的Action 類相對應。例如,struts-example 應用中就包含下面的action mapping:
<action path="/tour"
forward="/tour.htm">
</action>

struts-config.xml 文件可以包含全局forwards, 全局例外, controller 元素,消息資源元素以及plug-in 元素。XDoclet 不能產生這些元素。但是它可以和飽含這些配置元素的文件進行合并以產生完整的struts-config.xml 文件。Table 1-5列出了在創建struts-config.xm文件時XDoclet希望在mergedir屬性指定的目錄中找到的文件清單。
Table 1-5. 可以合并到產生的struts-config.xml文件中的配置文件 |
合并文件 |
用途 |
struts-data-sources.xml |
一個XML 文檔,包含可選的data-sources元素 |
struts-forms.xml |
一個XML 未解析的實體,包含form-bean 元素,作為非XDoclet forms的補充 |
global-exceptions.xml |
一個XML 文檔,包含可選的global-exceptions 元素 |
global-forwards.xml |
一個XML 文檔,包含可選的global-forwards 元素 |
struts-actions.xml |
一個可選的XML 未解析實體,包含action 元素,作為非XDoclet actions的補充 |
struts-controller.xml |
一個XML 文檔,包含可選的controller 元素 |
struts-message-resources.xml |
一個可選的XML 未解析實體,包含message-resources元素 |
struts-plugins.xml |
一個可選的XML 未解析實體,包含 plug-in 元素 |
大多數開發者都認為, XDoclet 對Struts 開發并不像他用在EJB 開發那么能干。比如,如果你在struts-config.xml中主要使用動態action forms ,那么從ActionForm 中產生form-bean 元素并不會為你帶來任何好處。但是,如果你開發一個具有大量action元素的大型應用,并使用Ant, 那么 XDoclet 則是值得考慮的。XDoclet 也支持其它類型的配置文檔,比如Hibernate mappings的生成。
相關招式
第1.7式提供了一個模版Ant build 腳本,你可以在其中添加XDoclet target。
關于XDoclet 的詳細信息訪問http://xdoclet.sourceforge.net.
你也可以閱讀Manning 出版Craig Walls和Norman Richards所著的Xdoclet in Action ,其中包括Xdoclet在Struts, Webwork, JDO, EJB,JMX, SOAP,Web Service 等方面開發的應用。http://www.manning.com/walls