DispatchAction, LookupDispatchAction, MappingDispatchAction的深入分析.我們來看一下它們3者的關系.
org.apache.struts.action.Action,                  --父類
org.apache.struts.actions.DispatchAction,       子類
org.apache.struts.actions.LookupDispatchAction,  子類
org.apache.struts.actions.MappingDispatchAction, 子類
DispatchAction, LookupDispatchAction, MappingDispatchAction都是繼承的Action類.

DispatchAction
定義

public abstract class DispatchAction extends Action
這是一個抽象的Action,它會根據request 中的parameter來執行相應的方法。通個這個Action類可以將不同的Action集中到一個Action文件中來。

Struts-config.xml:

<action path="/saveSubscription" type="org.apache.struts.actions.DispatchAction" name="subscriptionForm" scope="request" input="/subscription.jsp" parameter="method"/>

在Action中要有相應的方法:

Public class demoAction extends DispatchAction{

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

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

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

}

你就可以通過這樣的方法來訪問你的程序:


http://localhost:8080/myapp/saveSubscription.do?method=update


如果parameter中參數為空,則執行Action中unspecified方法


LookupDispatchAction
public abstract class LookupDispatchAction extends DispatchAction
通過這個Action抽象類繼承DispatchAction,它的相應方法的執行由 ActionMapping中parameter屬性決定。它適合在一個form中有很多按鈕,按不同的按鈕則執行不同的操作。

struts-config.xml:

<action path="/test"

type="org.example.MyAction"

name="MyForm"

scope="request"

input="/test.jsp"

parameter="method"/>

ApplicationResources.properties:


button.add=Add Record

button.delete=Delete Record

JSP:


<html:form action="/test">

<html:submit property="method">

<bean:message key="button.add"/>

</html:submit>

<html:submit property="method">

<bean:message key="button.delete"/>

</html:submit>

</html:form>

在Action 中必須實現getKeyMethodMap:


protected Map getKeyMethodMap() {

Map map = new HashMap();

map.put("button.add", "add");

map.put("button.delete", "delete");

return map;

}


public ActionForward add(ActionMapping mapping,

ActionForm form,

HttpServletRequest request,

HttpServletResponse response)

throws IOException, ServletException {

// do add

return mapping.findForward("success");

}


public ActionForward delete(ActionMapping mapping,

ActionForm form,

HttpServletRequest request,

HttpServletResponse response)

throws IOException, ServletException {

// do delete

return mapping.findForward("success");

}


MappingDispatchAction
public class MappingDispatchAction extends DispatchAction
它的相應方法的執行由 ActionMapping中parameter名決定,注意這里和LookupDispatchAction不同,LookupDispatchAction的相應方法的執行由 ActionMapping中parameter屬性決定,


struts-config.xml:

 

<action path="/saveSubscription"

type="org.example.SubscriptionAction"

name="subscriptionForm"

scope="request"

input="/subscription.jsp"

parameter="method"/>

Action:


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

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

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

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

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

for which you would create corresponding <action> configurations that reference this class:

 

<action path="/createSubscription"

type="org.example.SubscriptionAction"

parameter="create">

<forward name="success" path="/editSubscription.jsp"/>

</action>


<action path="/editSubscription"

type="org.example.SubscriptionAction"

parameter="edit">

<forward name="success" path="/editSubscription.jsp"/>

</action>


<action path="/saveSubscription"

type="org.example.SubscriptionAction"

parameter="save"

name="subscriptionForm"

validate="true"

input="/editSubscription.jsp"

scope="request">

<forward name="success" path="/savedSubscription.jsp"/>

</action>


<action path="/deleteSubscription"

type="org.example.SubscriptionAction"

name="subscriptionForm"

scope="request"

input="/subscription.jsp"

parameter="delete">

<forward name="success" path="/deletedSubscription.jsp"/>

</action>


<action path="/listSubscriptions"

type="org.example.SubscriptionAction"

parameter="list">

<forward name="success" path="/subscriptionList.jsp"/>

</action>


DispatchAction,LookupDispatchAction,MappingDispatchAction
1) DispatchAction就是在struts-config中用parameter參數配置一個表單字段名,這個字段的值就是最終替代execute被調用的方法. 例如parameter="method"而request.getParameter("method")="save",其中"save"就是MethodName。struts的請求將根據parameter被分發到"save"或者"edit"或者什么。但是有一點,save()或者edit()等方法的聲明和execute必須一模一樣。

2) LookupDispatchAction繼承DispatchAction, 用于對同一個頁面上的多個submit按鈕進行不同的響應。其原理是,首先用MessageResource將按鈕的文本和ResKey相關聯,例如button.save=保存;然后再復寫getKeyMethodMap(), 將ResKey和MethodName對應起來, 例如map.put("button.save", "save"); 其配置方法和DispatchAction是一樣的, 使用時要這么寫:

3) MappingDispatchAction是1.2新加的, 也繼承自DispatchAction. 它實現的功能和上面兩個區別較大, 是通過struts-config.xml將多個action-mapping映射到同一個Action類的不同方法上, 典型的配置就是:


然后UserAction繼承MappingDispatchAction,其中有:
public ActionForward save(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception
public ActionForward edit(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception
等方法

可以看到, 不管怎么變化, 其實這些類都是把execute給分解開, 不管是save, edit還是其他什么方法, 其實都是和原來的execute是等價的, save和edit之間沒有任何直接的關系, 而事實呢,它們是同一個業務模型的兩種不同操作。 我覺得這就是一個問題,對于save和edit這兩種請求, 我后臺邏輯有可能只是調用service的方法那一句不一樣,其他代碼是完全一致的(例如錯誤處理, 日志記錄等)。因此我想出了這個小東西,在execute方法內部進行局部分解