第1.8式. 使用XDoclet 產(chǎn)生Struts配置文件
問(wèn)題
當(dāng)你修改或者新建一個(gè)Action 或ActionForm時(shí),你需要修改對(duì)應(yīng)的Struts 配置文件。
動(dòng)作要領(lǐng)
使用XDoclet 工具,配合Ant,來(lái)處理Java代碼中可以自動(dòng)產(chǎn)生truts-config.xml文件的注解。
動(dòng)作變化
現(xiàn)在的大多數(shù)應(yīng)用軟件系統(tǒng)都有可執(zhí)行代碼文件文本配置文件組成。這種方式可以使你更容易的在各種不同的環(huán)境之間移植,并且減少必須針對(duì)各種不同部署而修改的代碼量。但是它帶來(lái)了另外一個(gè)負(fù)擔(dān),那就是保持代碼和配置文件之間的一致性。
XDoclet 工具,原本開(kāi)發(fā)來(lái)是針對(duì)EJB的開(kāi)發(fā),它就可以解決這個(gè)問(wèn)題。通過(guò)XDoclet,開(kāi)發(fā)者能夠在代碼中放置能夠描述與代碼相關(guān)的配置屬性的注解,這些注解非常類似于JavaDoc 標(biāo)簽。在構(gòu)建時(shí),你可以使用定制的Ant 任務(wù),由它來(lái)使用XDoclet 從而處理這些標(biāo)簽并產(chǎn)生對(duì)應(yīng)的XML 配置文件。
對(duì)Struts來(lái)說(shuō),XDoclet 可以產(chǎn)生struts-config.xml文件中的下列元素:
另外, XDoclet 還可以創(chuàng)建字段級(jí)的Struts Validator 配置,通常是位于validation.xml 文件之中。最后,如果你要映射EJB 實(shí)體Bean的屬性到Struts ActionForms, XDoclet 可以不產(chǎn)生ActionForm 的Java 源代碼。
首先,你需要添加一個(gè)任務(wù)到你的Ant 的build 腳本文件中,該任務(wù)可稱為XDoclet 任務(wù)。Example 1-9展示了一個(gè)為struts-example 應(yīng)用產(chǎn)生struts-config.xml 文件的Ant任務(wù)。
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>

這個(gè)目標(biāo)(target)調(diào)用webdoclet 定制Ant任務(wù),它是由XDoclet提供的。此任務(wù)可以產(chǎn)生多個(gè)Web應(yīng)用相關(guān)的工件,包括 web.xml 文件, struts-config.xml 文件,validation.xml 文件。對(duì)Struts 應(yīng)用來(lái)說(shuō),你可能不需要產(chǎn)生web.xml 文件;因?yàn)閷?duì)Struts 應(yīng)用,該文件并不經(jīng)常改變。在Example 1-9中,webdoclet 任務(wù)被用于產(chǎn)生struts-config.xml 文件。
并不是所有的struts-config.xml 文件中的元素都可以或者應(yīng)該從注解的代碼中產(chǎn)生。像全局forward, 全局例外處理,消息資源,插件等都并不和特定的Action 或ActionForm 類相關(guān)。
XDoclet 是通過(guò)讓你在位于特定的目錄中的文件中放置靜態(tài)配置來(lái)處理這些事情的。在構(gòu)建時(shí), XDoclet 將這些文件中代碼中產(chǎn)生的元素進(jìn)行合并。你可以通過(guò)mergedir 屬性來(lái)指定這些靜態(tài)文件的位置。destdir 屬性則指定將創(chuàng)建的文件的存放目錄。通常,你需要為這些產(chǎn)生的文件創(chuàng)建一個(gè)單獨(dú)的目錄,然后在其成功創(chuàng)建后將它們拷貝到適當(dāng)?shù)哪夸浿幸还泊虬蛘卟渴稹xcludedtags 屬性指定排除在XDoclet 處理之外的JavaDoc 標(biāo)簽。
|
執(zhí)行@author和 @version標(biāo)簽是通用的。 |
最后, force 屬性強(qiáng)制XDoclet 產(chǎn)生一個(gè)新的配置文件。如果這個(gè)屬性為false, 新文件只有在對(duì)應(yīng)的注解Java代碼發(fā)生改變時(shí)才會(huì)產(chǎn)生。
fileset 元素告訴XDoclet 要處理哪些Java 源文件。你可以使用該元素來(lái)指示那個(gè)源文件包含XDoclet 注解。例如,struts-example 應(yīng)用使用了兩個(gè)Struts 配置文件:struts-config.xml 和 struts-config-registration.xml。如Example 1-9所示,你可以通過(guò)設(shè)置fileset元素來(lái)排除包含名稱"Registration"的類從而排除放入struts-config-registration.xml 文件中的元素。
strutsconfigxml 元素指示XDoclet 產(chǎn)生struts-config.xml 文件。XDoclet 默認(rèn)情況下將產(chǎn)生Struts 1.0兼容的配置文件。因此,如果你用Struts1.1你必須指定版本為"1.1"。XDoclet 也使用該屬性提供對(duì)Struts 1.2 的支持。
一旦你在構(gòu)建文件中創(chuàng)建了這個(gè)target,你就可以添加注解到Action 和ActionForm 類的代碼中。對(duì)ActionForm, XDoclet 提供了@struts.form 標(biāo)簽來(lái)產(chǎn)生form-bean 元素。下面的代碼展示了如何在struts-example 應(yīng)用的SubscriptionForm中使用這個(gè)類一級(jí)的標(biāo)簽:

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


public final class SubscriptionForm extends ActionForm
{

}

在webdoclet target 被執(zhí)行時(shí),將在struts-config.xml 中產(chǎn)生下面的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 使用你在標(biāo)簽中指定的名稱來(lái)產(chǎn)生form-bean 元素,并且使用ActionForm 的權(quán)限定類名來(lái)創(chuàng)建type 屬性。這一特征也是XDoclet最大的優(yōu)點(diǎn)之一。你的類的屬性,比如類名、包名、方法名等,對(duì)XDoclet 都可使用,就像它們被用于產(chǎn)生Javadocs 一樣。XDoclet 將在產(chǎn)生的文件的適當(dāng)位置使用這些值。
|
如果你修改了一個(gè)類的類名或者包名, XDoclet將產(chǎn)生正確的配置元素而不會(huì)混淆。雖然IDE 的重構(gòu)工具也可以處理這種類型的改變,但是使用XDoclet這是另外一種可以集成到現(xiàn)有的Ant構(gòu)建過(guò)程中的解決方案。 |
你可以使用XDoclet 來(lái)從Action類中產(chǎn)生action 元素。XDoclet 使用@struts.action 標(biāo)簽來(lái)指定action 元素。另外,@struts.action-forward 標(biāo)簽則可以指定嵌套的forward 元素。同時(shí)@struts.action-exception標(biāo)簽可以用于產(chǎn)生action特定的宣稱性例外處理。struts-example 中的LoginAction.java 類示于下方,其中還包括產(chǎn)生完整的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
{

}

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

/**//**
* 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 對(duì)產(chǎn)生struts-config.xml 文件大有幫助,它也并不是萬(wàn)能的。某些action 元素并不與任何你創(chuàng)建的Action 類相對(duì)應(yīng)。例如,struts-example 應(yīng)用中就包含下面的action mapping:
<action path="/tour"
forward="/tour.htm">
</action>

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