2009年2月14日 星期六

[Struts2] 組織 Actions

雖然說 Action 是 Struts2 中核心的元件,但是沒有了 struts-config.xml,這些我們辛苦撰寫的 Actions 也是英雄無用武之地~在 初啼試聲 HelloStruts2 中,我們定義了一個 struts-config.xml 來告知 Struts2:我們的 Actions 要怎樣去使用。而且這些 Actions 都會被組織到一個 logical container 叫做 package 之中。Struts2 中的 package 觀念其實跟 JAVA 的 package 觀念很類似,他們都是提供一種機制讓 programmers 可以很方便的組織與規劃各個 Actions 之間的群組,我們可以利用這樣的機制並根據 Actions 所提供的功能來加以分群組織。例如,我們可以將我們的網站分為:使用者登入登出、使用者瀏覽與使用者下訂單等等,每組的功能可以包裝成一個 package,而這一個 package 中又有一些 Actions 提供核心的功能,然後我們在藉由 struts.xml 來組織我們的 packages。換句話說,在 Struts2 中 struts.xml 是最上層的 package,而我們可以在 struts.xml 中加入其他我們另外定義的 packages(也是一個符合struts-2.0.dtd 的 .xml 檔案)。

<package> tag 探討

在 configuration 檔案中,主要用來組織 Actions 的就是 <package> tag,在 package tag 之下,我們利用 <action> tag 來對應到我們所撰寫的 Action。以下就是 package tag 可以設定的 attributes:

Attribute Description

name
(必須)

package 的 name,可以作為其他 packages 繼承之用
namespace package 中的所有 actions 所對應到的 namespace
extends 此 package 所繼承的其他 package 名稱
abstract 如果設定為 true,則此 package 只能被用來繼承,package 中不能有任何的 Actions 的設定

由上面的表格中我們可以了解到 package tag 中的四種 attributes,讓我們回顧一下當初在 初啼試聲 HelloStruts2 中所撰寫的 struts.xml 檔案。



<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.devMode" value="true" />
<package name="hello" extends="struts-default">
<action name="Hello" class="silver8250.hello.HelloUser">
<result name="success">/WEB-INF/pages/hello_user.jsp</result>
</action>
</package>
</struts>

每一個設定檔案都是要以 <struts> tag 作為 root node,這也是 W3C 對於 well-form xml 的定義,接下來我們對於 package 給予一個 name 為 hello,他是繼承 struts-default,主要是在 Struts2 中所提供的 struts-default.xml 檔案(你可以在 struts2-core-[verson].jar 中找到,或是參考官方網站的資料),而 namespace 則是設定在這個 package 之下的所有 Actions 被呼叫時的上層 URL,舉個例子,假設我們的 package 設定為<package name="Test" namespace="/Hello/Struts">,然後我們有一個 Action 為 HelloUser,當我們要透過 URL 呼叫 HelloUser 這個 Action 時,我們就要輸入: http://localhost:8080/TestProject/Hello/Struts/HelloUser.action ,(我們的 web server 是跑在 port 為 8080 上,並且我們的 web app 名稱為 TestProject),這樣你應該可以更瞭解 namespace 所代表的意義。如果說我們像上面的 struts.xml 檔案一樣沒有設定 namespace 的話,就會是預設的設定值,也就是 namespace=""。最後一項 attribute 就是 abstract,這個 attribute 只能給予 boolean value(true / false),如果我們設定 abstract="true",那就意味著我們現在的設定檔的 package tag 中不能包含任何的 <action> tag,也就是不能加入 Actions,這樣的設計是來自於 Java 的 Abstract class 概念,如果我們沒有設定,則預設值是 abstract="false"。

struts.xml 探討

既然 struts.xml 是最上層的設定檔,而且我們又可以自己設定其他的設定檔案,那就意味著 Struts2 有提供特別的功能來支援,沒錯!<include> tag 就是被設計用來支援這樣的功能。在官方文件中很生動的說明了這種功能 - divide and conquer,學過演算法的應該可以瞭解這個精神!這個 include tag 是隸屬於 struts tag 之下的:



<struts>
<include file="/silver/test/other.xml"/>
</struts>

從上面的設定檔中我們加入了一個 include tag,而 include tag 只有一個 attribute 為 file,是用來指定該設定檔的,如上面所撰寫的代表有一個 other.xml 檔案(符合 struts-2.0.dtd 的規則)並且被放置於 /silver/test/ 目錄之下,也就是放在 silver.test 的 Java package 之下。利用這樣的方式,我們的網站就可以根據不同組的功能來分別開發,最後再到 struts.xml 檔案中作結合。

1 則留言:

Unknown 提到...

大大
看了你的教學
受益良多啊