在struts1中,我们知道在客户端发送“
url.do”时由前端控制器ActionServlet分派给RequestProcessor来处理客户请求,最后分发给相应的应用程序控制器Action来处理业务,那么在一个应用程序中,如果有n个业务请求就需要n个action来处理,相应就需要n个action类文件,一个Action中只有一个execute方法,如果我们把某一个功能模块的所有方法放在一个Action类文件中,把不同的业务放在不同的方法中,并且由ActionServlet统一进行分发,岂不妙哉!在struts1中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 TestAction 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
这样,我们就完成了action中方法的分发。可以大大减少action文件的数量。
一直以来,我个人不太喜欢DispatchAction的做法:
1、
把action的方法名称暴露在界面上,给人的感觉总是有种“上身穿西装,下神是裸体”的感觉。
2、
如果阅读一个请求,需要从界面的请求开始看起,经历struts-config.xml然后才能到对应的action方法,感觉太麻烦。
3、
如果一个action中的请求中使用不同的form对象,在这样的程序中就感觉非常难受。
4、
DispatchAction使用execute做进一步的方法分发,如果我们使用DispatchAction,就不能使用execute方法了。
5、
如果方法的分发不是由界面决定的,只是由struts-config.xml决定的就感觉好多了。
尽管有一个LookupDispatchAction
可以根据界面不同按钮进行分发,感觉还不是很满意,struts1.2中又提出了MappingDispatchAction,这个action比较符合我的想法,但是MappingDispatchAction是继承自DispatchAction,骨子里还是DispatchAction,照样不能使用默认的execute方法。
有没有更好的办法既让执行默认的execute方法,又可以根据配置文件来执行parameter规定的方法呢?
也许有,我还不知道,我也不想去找了,干脆我来做一个,懒得费精力去搜索:
理论:
当客户端发送请求“url.do”到ActionServlet时,servlet会调用RequestProcessor来处理客户端的请求,RequestProcessor类中有很多processXXX方法:
ProcessPreProcess
最先调用的方法,决定struts是否继续向下处理。
processPath 获取客户端的请求路径
processMapping 利用路径来获得相应的ActionMapping
processActionForm
初始化ActionForm(如果需要)并存入正确的scope中
processActionCreate 初始化Action
processActionPerform
调用Action的execute方法
processForwardConfig 处理Action返回的ActionForward
其中processActionPerform
是调用Action的execute方法,我们重新写这个方法利用反射就可以搞定我们想要的操作。
具体的代码如下:
public class DispatchRequestProcessor extends RequestProcessor
{
//规定action中的方法参数类型,必须与execute方法的参数类型一致。返回值必须是ActionForward
final
Class[] types=new Class[]{ActionMapping.class,
ActionForm.class,
HttpServletRequest.class,
HttpServletResponse.class};
@Override
protected
ActionForward processActionPerform(
HttpServletRequest request,
HttpServletResponse response,
Action action,
ActionForm form,
ActionMapping mapping) throws IOException, ServletException {
try {
//从struts-config.xml中的parameter属性中获取需要调用的方法名称,如果方法名不存在,就调用默认的execute方法。
String methodName=mapping.getParameter();
if (methodName==null || methodName.length()==0)
{
return action.execute(mapping, form, request, response);
}
//利用反射找到需要调用的action中的方法Method
Method method=action.getClass().getMethod(methodName, types);
//调用action中方法时准备的方法参数
Object[] args=new Object[]{
mapping,
form,
request,
response
};
//调用action中的方法,结果result就是ActionForward对象
Object result=method.invoke(action, args);
return (ActionForward) result;
} catch (Exception e) {
e.printStackTrace();
response.sendError(500,e.getMessage());
}
return null;
}
}
这个控制器就可以从配置文件中读取action中要调用的方法,如果方法没有存在还可以自动调用execute方法。与界面没有任何关系,界面的请求还是普通的action请求,配置文件需要修改。
例如:
<action
attribute="userForm"
input="/form/user.jsp"
name="userForm"
path="
/userAdd"
scope="request"
parameter="
add"
type="com.yourcompany.struts.action.UserAction" >
<forward name="ok" path="/userSelect.do" />
</action>
<action
attribute="userForm"
name="userForm"
parameter="
update"
path="/
userUpdate"
scope="request"
type="com.yourcompany.struts.action.UserAction">
<forward name="ok" path="/userSelect.do" />
</action>
<!--没有parameter属性,默认处理,将调用execute方法
-->
<action
path="/
userSelect"
type="com.yourcompany.struts.action.UserAction">
<forward name="ok" path="/ok.jsp" />
</action>
对应的Action变化是,不但有默认的execute方法,还可以有其他的方法。
public class UserAction extends Action {
//处理struts-config.xml中没有parameter属性的操作
,select
public
ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {
}
public
ActionForward add(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {
}
public
ActionForward update(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {
}
}
这样,主要的地方是修改了控制器,别的地方都没有修改,就完成了方法的分发。
分享到:
相关推荐
DispatchAction是Struts提供的一个可扩展的Action类,它允许开发者将一个单一的Action类拆分成多个子方法,每个子方法处理特定的业务逻辑,从而提高了代码的组织性和可维护性。 DispatchAction的工作原理是通过...
在Struts2中,Action是处理用户请求的核心组件。它负责业务逻辑的执行,并将结果返回给视图进行展示。本篇文章将详细介绍Struts2 Action的三种访问方式:传统方式、通配符方式和动态方式。 1. **传统方式(Static ...
9. **Dispatcher Training**:在struts_iBATIS_dispatch_trainning_usermgr中,“dispatcher”可能指的是请求调度器,这可能是一个训练示例,展示了如何在Struts中实现请求的分发和用户管理。 10. **用户管理**:从...
03Struts2常用标签&DispatchAction.rar03Struts2常用标签&DispatchAction.rar03Struts2常用标签&DispatchAction.rar03Struts2常用标签&DispatchAction.rar
`DispatchAction`是Struts提供的一个扩展自`Action`类的预定义动作,它的主要目的是通过不同的方法来处理来自客户端的请求,而不是像标准的`Action`那样只有一个处理所有请求的方法。这种设计使得代码结构更清晰,更...
connectify dispatch 4.0完美破解版
Dispatch IDS for IExplorer Dispatch Events
7. **struts2_dispatch**:这部分可能涉及到Struts2的请求分发机制。Struts2提供了多种URL映射方式,如基于方法的映射、基于通配符的映射等,使得请求的处理更加灵活。 通过以上子文件的学习,你可以掌握Struts2的...
Dispatch 是StrangeIOC中的一个重要概念,它用于处理事件分发,帮助我们构建MVCS(Model-View-Controller-Servant)架构。在MVCS模式下,Dispatch起到了连接View和Controller或者Servant的桥梁作用,使得View能够...
注册汉化方法: 双击“Installer”安装...复制Crack目录中的dispatch.dll和web文件夹到软件安装目录中的\plugins\dispatch目录覆盖同名文件。 复制Crack目录中的connectify.exe文件到安装程序目录覆盖同名文件。
1、通过dispatch_barrier_(a)sync添加的block会等待前边所有的block执行完(不包括回调)才执行。 2、在其后添加的block会在dispatch_barrier_(a)sync添加的block执行完之后(不包括回调)再执行; 不同点: 1、...
以上两种方式都是模拟任务block内为异步操作的情况,方式一先执行的dispatch_group_notify里的代码,后执行的dispatch_group_async里的任务代码,这与我们的初衷相违背。如果任务block内为同步操作时,则无论哪种...
DispatchAction继承自Struts的基础Action类,它通过一个名为`dispatch()`的方法来决定哪个方法应该处理特定的请求。这个方法会根据请求参数(通常是请求路径或请求参数中的一个属性)来选择并调用对应的方法。例如...
1、struts资源文件中文解决方法 1 2、开发struts2流程 1 3、创建拦截器: 2 4.标签中引用资源文件内容 3 5.创建资源文件 3 6.Action中访问servlet API 3 7.Action访问资源文件 3 8.资源文件_各国代码 4 9.将...
`DispatchSemaphore`提供了两个主要方法: 1. `wait(timeout:)`:此方法用于获取信号量,如果当前信号量值为0,则线程会被阻塞,直到其他线程释放信号量或超时。超时参数可以是` DISPATCH_TIME_FOREVER`(无限等待...
Action Dispatch Error(解决方案).md
这里,`struts.enable.SMD`配置项允许使用SMD(Simple Method Dispatch),`struts.action.extension`添加了JSON作为Action的扩展名,`struts.json.excludeProperties`则用于排除某些敏感属性,防止它们被序列化为...
Title : dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent三者对MotionEvent的分发、拦截机制分析 Author: yaong Category:自己做的Demo Tips : 三个自定义View,依次嵌套,并各自覆写拦截、监听方法,通过...
关于grasshopper的基础练习,dispatch案例的电池资源。