簡介 Action


在請求來臨後,RequestProcessor 根據請求URI呼叫對應的Action物件,將工作交給它,並在最後由Action物件得到一個ActionForward物件, ActionServlet使用ActionForward得知將流程forward至指定的資源。

當請求到達時,會檢查對應的Action物件是否存在,如果不存在則生成一個,之後一直使用它,由於Action物件會一直存在,所以使用Action物件必須注意到執行緒安全問題。

Action類別的使用是繼承它,在Struts 1.1後會重新定義execute()方法,在Struts 1.0中的perform()方法已經不建議使用;execute()方法有兩個接收不同參數的版本:
public ActionForward execute(ActionMapping mapping,
                              ActionForm form,
                              ServletRequest request,
                              ServletResponse response)
                                  throws Exception;

public ActionForward execute(ActionMapping mapping,
                              ActionForm form,
                              HttpServletRequest request,
                              HttpServletResponse response)
                                  throws Exception;
 

由於Action通常處理HTTP相關請求,所以常會使用第二個方法,execute()方法最後要傳回ActionForward物件給 RequestProcessor,來回顧一下 第一個 Struts 程式 中的HelloAction的例子:
  • HelloAction.java
package onlyfun.caterpillar;

import java.util.*;
import javax.servlet.http.*;
import org.apache.struts.action.*;

public class HelloAction extends Action {
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {

// get information from request object
String username = request.getParameter("user");

// no more carrying information from client
request.removeAttribute("user");

// prepare model
Map model = new HashMap();
if(username != null)
model.put("username", username);
else
model.put("username", "nobody");

// pass information to View by using reqeust object
request.setAttribute("userInfo", model);

return mapping.findForward("helloUser");
}
}

這要配合struts-config.xml中的請求URI與對應的Action設定,所以改寫 第一個 Struts 程式 的struts-config.xml設定:
  • struts-config.xml
<?xml version="1.0" encoding="ISO-8859-1" ?>

<!DOCTYPE struts-config PUBLIC
 "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
 "http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd">
<struts-config>
    <global-forwards>
        <forward
            name="welcome"
            path="/welcome.do"/>
    </global-forwards>

    <action-mappings>
        <action
             path="/welcome
             type="org.apache.struts.actions.ForwardAction"
             patameter="/WEB-INF/pages/welcome.jsp"/>

        <action
             path="/hello"
             type="onlyfun.caterpillar.HelloAction">
             <forward
                 name="helloUser"
                 path="/WEB-INF/pages/hello.jsp"/>
         </action>
     <action-mappings>
</struts-config>

在 MVC / Model 2 中,理想上所有客戶端的請求都經由Controller來協調轉發,客戶端不會直接指定真正的位址來請求資源。

在上面使用了一個Struts所提供的org.apache.struts.actions.ForwardAction類別,它是 Action的一個子類,當客戶端請求了/welcome.do時,就會呼叫這個Action,它會直接進行請求轉發,轉發的對象是parameter中 所設定的對象,一個應用的例子是當使用者請求的參數或方式錯誤時,可以使用mapping.findForward("welcome")來將使用者轉發 至welcome.jsp頁面。

有時候您也會需要引入一個頁面或資源,這時您可以使用org.apache.struts.actions.IncludeAction,同樣的也是 Action子類,其設定方式與ForwardAction相同,只不過它是用 include的方式來調用頁面或資源:
...
       <action
            path="/someresource"
            type="org.apache.struts.actions.IncludeAction"
            parameter="/path/someResource"/>
 ...

Action物件是Controller角色,在Action物件中的邏輯最好只與Web層的資料準備有關,而不涉及商務邏輯,基本上在Action 中您所要作的是:
  • 取得請求中的相關參數(或是從表單物件中取得)
  • 驗證資料的邏輯正確性(或由表單物件進行驗證)
  • 將請求參數複製給商務物件
  • 取得執行結果並準備View所需的資料Model
  • 轉發給View物件