Struts 1 中关于Action 的方法分发dispatch
在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) {
}
}
这样,主要的地方是修改了控制器,别的地方都没有修改,就完成了方法的分发。
相关推荐
在Struts框架中,`DispatchAction`和`MappingDispatchAction`是两种常见的控制器组件,用于处理用户请求。它们是Action接口的实现类,主要用于映射HTTP请求到特定的方法,从而实现业务逻辑的分发。 首先,让我们...
在实际开发中,Struts通过Model 2模式改进了早期Web项目的MVC实现。JSP Model 1混合了业务逻辑和视图,而Model 2则将它们分离,使用Servlet作为控制器,JSP作为视图,JavaBeans作为模型。尽管Model 2有所改进,但...
6.3 Log4j的使用方法 6.3.1 配置Log4j 6.3.2 配置根Logger 6.3.3 指定日志输出位置 6.3.4 指定日志输出格式 6.3.5 指定日志输出优先级 6.3.6 在代码中使用Log4j 6.4 改进Log4j 6.5 小结 第七章 Ant使用指南 7.1 Ant...
以上是赖家材老师的 Struts 传智播客笔记中关于 Struts 的基础和高级知识点的详细介绍,涵盖了 Struts 的入门概念、工作原理以及高级功能等方面的内容。这些知识点对于初学者来说非常宝贵,能够帮助他们快速掌握 ...
6.3 Log4j的使用方法 6.3.1 配置Log4j 6.3.2 配置根Logger 6.3.3 指定日志输出位置 6.3.4 指定日志输出格式 6.3.5 指定日志输出优先级 6.3.6 在代码中使用Log4j 6.4 改进Log4j 6.5 小结 第七章 Ant使用指南 7.1 Ant...
### Struts基础入门知识点 #### 一、Struts1简介 Struts1 是一款用于构建...然而,随着技术的发展,Struts1的一些设计已经显得有些过时,Struts2作为其继任者,在保留原有优势的基础上,进一步改进了性能和易用性。
6.3 Log4j的使用方法 6.3.1 配置Log4j 6.3.2 配置根Logger 6.3.3 指定日志输出位置 6.3.4 指定日志输出格式 6.3.5 指定日志输出优先级 6.3.6 在代码中使用Log4j 6.4 改进Log4j 6.5 小结 第七章 Ant使用指南 7.1 Ant...
Struts ActionForm是Java Web开发中Struts框架的一个核心组件,它主要负责在控制器层(Controller)和视图层...理解ActionForm的工作原理和使用方法,有助于我们更有效地利用Struts框架构建高质量的Java Web应用。
- **Struts1**:Action类必须继承自特定的基类,如`Action`或`DispatchAction`,并且需要实现特定的方法(如`execute`)来处理请求。 - **Struts2**:Action可以是任意的Java对象(即POJO),这极大地简化了开发...
6. **Struts支持**:XDoclet可以帮助生成Struts的ActionForm、Action和DispatchAction等类,以及struts-config.xml配置文件。 7. **运行与集成**:XDoclet可以作为一个独立的命令行工具运行,也可以集成到构建工具...
6.3 Log4j的使用方法 6.3.1 配置Log4j 6.3.2 配置根Logger 6.3.3 指定日志输出位置 6.3.4 指定日志输出格式 6.3.5 指定日志输出优先级 6.3.6 在代码中使用Log4j 6.4 改进Log4j 6.5 小结 第七章 Ant使用指南 7.1 Ant...
- 实现了类似于Struts的`DispatchAction`,继承该类的Servlet可以通过指定方法名的方式调用相应的方法。 - 用户登录后,可以获取到`CURRENT_USER`和`ACCESS_LEVEL`两个属性。 - **继承后可访问属性:** - `out`: ...