一 开文背景 -- 废话讲一段~

  本文借助动力节点-王勇老师的视频教程中的引例来了解struts1的实现原理,虽然现在已经很少使用struts1了,但是了解了其原理之后,对了解其他mvc框架还是有较大的帮助的.

二 简介 -- 切入主题

  struts1主要实现从请求到servlet的映射.

  e.g. 现有的一个业务为实现用户的添加删除修改,按照原有的model2的原理可以实现上述功能.

  2.1没有struts1之前的基于model2 mvc的实现.

  直接在servlet中实现如下代码:

        String username = request.getParameter("username");
UserManager userManager = new UserManager();
String forward = "";
if ("/servlet/delUser".equals(path)) {
userManager.del(username);
forward = "/del_success.jsp";
}else if ("/servlet/addUser".equals(path)) {
userManager.add(username);
forward = "/add_success.jsp";
}else if ("/servlet/modifyUser".equals(path)) {
userManager.modify(username);
forward = "/modify_success.jsp";
}else if ("/servlet/queryUser".equals(path)) {
List userList = userManager.query(username);
request.setAttribute("userList", userList);
forward = "/query_success.jsp";
}else {
throw new RuntimeException("请求失败");
}
request.getRequestDispatcher(forward).forward(request, response);

  到现在,基本的功能是已经实现了,但是看着上面的代码就像吐啊~一坨的if-else,复杂的每一个if-else节点处理~毫无半点的扩展性可言.

  解决办法:

    将每一个小的业务处理单独来处理.抽象出一个借口Action,抽象方法:execute(HttpServletRequest,HttpServletResponse). struts1中返回一个ActionForword对象.

          public interface Action {

public String execute(HttpServletRequest request, HttpServletResponse response)
throws Exception;
}

  每一个小的功能(添加\删除\修改),都抽象成一个action,实现上面的接口.

  

 Action action = null;
if ("/servlet/delUser".equals(path)) {
action = new DelUserAction();
}else if ("/servlet/addUser".equals(path)) {
action = new AddUserAction();
}else if ("/servlet/modifyUser".equals(path)) {
action = new ModifyUserAction();
}else if ("/servlet/queryUser".equals(path)) {
action = new QueryUserAction();
}else {
throw new RuntimeException("请求失败");
}
String forward = null;
try {
forward = action.execute(request, response);
} catch (Exception e) {
e.printStackTrace();
}
request.getRequestDispatcher(forward).forward(request, response);

  虽然相对上面的"代码",这次有了一定程度的提高(仅仅是思想上),代码的扩展性,还是没有达到要求的.

  如今,对一些较多可选择性的代码,将其从代码中抽离出来,转化为配置文件是提高扩展性的一种方式.

 /
<action-config>
<action path="/servlet/delUser" type="com.bjpowernode.servlet.DelUserAction">
<forward name="success">/del_success.jsp</forward>
<forward name="error">/del_error.jsp</forward>
</action <action path="/servlet/addUser" type="com.bjpowernode.servlet.AddUserAction">
<forward name="success">/add_success.jsp</forward>
<forward name="error">/add_error.jsp</forward>
</action <action path="/servlet/modifyUser" type="com.bjpowernode.servlet.ModifyUserAction">
<forward name="success">/modify_success.jsp</forward>
<forward name="error">/modify_error.jsp</forward>
</action <action path="/servlet/queryUser" type="com.bjpowernode.servlet.QueryUserAction">
<forward name="success">/query_success.jsp</forward>
<forward name="error">/query_error.jsp</forward>
</action </action-config>

  每一个<action></action>结点指定该action对应的请求路径,对应处理该请求的具体Action类型,以及处理之后的转向.在装载这些配置文件需要一个对象来装填,这就是ActionMapping类型.

         /
ActionMapping {
private String path;//请求路径
private String type;//对应的处理该请求的action类型.
Map forwardMap; //处理完成之后的跳转信息.
/

  同样,需要将跳转信息保存起来,实现对象为ForwordMap<key,value>

         /
}
forwardMap {
key="success";
value="/del_success.jsp"
key="error"
value="/del_error.jsp"
}
/

  在struts1中使用Map将这些action保存起来Map<request_url,ActionMapping>.在actionmapping中同样保存着request_url.

            Map map = new HashMap();
map.put("/servlet/delUser", actionMapping1);
map.put("/servlet/addUser", actionMapping2);
map.put("/servlet/modifyUser", actionMapping3);
map.put("/servlet/queryUser", actionMapping4);

  如果是删除ActionMapping存储如下:  

            actionMapping {
path= "/servlet/delUser";
type = "com.bjpowernode.servlet.DelUserAction";
forwardMap {
key="success",value="/del_success.jsp"
key="error", value="/del_error.jsp"
}
}

  三 综合总结

  下面就使用一个例子来总结一下整个struts1的处理流程

    String path = "/servlet/delUser";

    1.根据截取的URL请求,到Map(从配置文件中获取)中取得本次请求对应的Action
    ActionMappint actionMappint = (ActionMappint)map.get(path);

    2.取得本请求对应的Action类的完整路径
    String type = actionMappint.getType(); //com.bjpowernode.servlet.DelUserAction

    3.采用反射动态实例化Action
    Action action = (Action)class.forName(type).newInstance();

    4.动态待用Action中的execute方法
    String forward = action.execute(request, response);

    5.根据路径完成转向
    request.getRequestDispatcher(forward).forward(request, response);

  真正来驱动这一切行为的操作者为Servlet,也就是MVC中的控制器,实现了请求url的截取,然后从配置文件中按照截取的url,来实现分发.读取配置文件,创建actionmapping,forwardmap对象,由此创建action对象,实现业务的处理,然后转向.

Struts1的实现原理的更多相关文章

  1. struts1和struts2原理解析

    1.struts1和struts2 是2个完全不同的框架 其实struts2核心就是 webwork框架 struts1以ActionServlet作为核心控制器,由ActionServlet负责拦截 ...

  2. struts1之工作原理

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/zkn_CS_DN_2013/article/details/34452341 1.初始化:strut ...

  3. struts1 工作原理

    struts1的原理和工作流程 struts1的工作原理或者说工作流程: 1.在web应用程序启动就会加载ActionServlet,ActionServlet从配置文件struts-config.x ...

  4. struts1与struts2的区别

    Struts2其实并不是一个陌生的Web框架,Struts2是以Webwork的设计思想为核心,吸收了Struts1的优点,因此,可以认为Struts2是Struts1和Webwork结合的产物. 简 ...

  5. Liferay JSP中常用的标签

    (本文转载自http://www.cnblogs.com/edwardlauxh/archive/2010/03/26/1918614.html) 在Liferay框架中拥有它自身的标签,虽然Port ...

  6. Java知识总结

                                                                                                         ...

  7. Struts的前世今身

    1.Struts1的运行原理 a.初始化:struts框架的总控制器ActionServlet是一个Servlet,它在web.xml中配置成自动启动的Servlet,在启动时总控制器会读取配置文件( ...

  8. Java框架知识点总结

    一.Struts1的运行原理 在启动时通过前端总控制器ActionServlet加载struts-config.xml并进行解析,当用户在jsp页面发送请求被struts1的核心控制器ActionSe ...

  9. Struts1——从BeanUtils看struts的实现原理2

        上一篇博客中我们简单的介绍了BeanUtils的使用.以及其最主要的原理,今天我们进一步的理解这个类在Struts1中的使用.     首先我们先回想一下搭建一个简单的基于Struts1框架的 ...

随机推荐

  1. ssh免密钥登录

    说明:下文中说的 '客户端'指的是你所使用的本地机器; '服务端'指的是远程你要连接的机器; ----------------------------------------------------- ...

  2. python mysql多条插入

    程序的目的是把文本里面的数据存储到数据库中,原来的思路是读一条,插入一条,结果就是时间长的不得了...18万条的数据,真是慢. 后来的想法是把所有的记录都读到一个list里,结果是mysql奔溃go ...

  3. [Windows编程] 开发DLL必读《Best Practices for Creating DLLs》

    开发DLL的时候,需要十分注意 DllMain 函数,因为在多线程环境下DLLMain里面的代码很容易引发线程死锁. 这篇MSDN文章<Best Practices for Creating D ...

  4. http://qt-project.org/wiki/Category:Developing_with_Qt::QtWebKit#ff7c0fcd6a31e735a61c001f75426961

    404: Not Found | Qt Project QtWebKit documentation http://dwz.cn/hr2013

  5. ecshop标签大全 各个页面常用标签大全

    先从index.php主页开始 页面关键字 {$keywords } 页面标题 {$page_title} 产品分类 父分类列表 {foreach from=$categories item=cat ...

  6. Google启封后依然不能用

    门事件周年纪念日过后一段时间,狗狗启封了,但撸主的狗狗仍旧不能用,突然想起来之前帆樯时候改动了某些配置,比方hosts文件,这个文件的路径为:C:\Windows\System32\drivers\e ...

  7. js动画学习(二)

    四.简单动画之缓冲运动 实现速度的缓冲,即不同位置的速度不同,越靠近目标值速度越小,所以速度值与目标值与当前值之差成正比.这里要注意一个问题就是物体在运动中速度是连续变化的,不是按照整数变化的,当物体 ...

  8. PHP - 数组去重,(折中:符串去重)

    [译]更快的方式实现PHP数组去重 Jan 11, 2016 • Hector 原文:Faster Alternative to PHP’s Array Unique Function 概述 使用PH ...

  9. React Native-目前最火的前端技术?

    做为一名产品经理,你是否遇到过这样的窘境,“帮我把字体调成 16号呗,颜色变成 #FFFF00FF,老大说这里最好改一下”,作为一名 app 的开发只能无奈但心里窃喜的告诉你,“只能等下个版本了,必须 ...

  10. BZOJ 1820: [JSOI2010]Express Service 快递服务( dp )

    dp(i,j,k)表示在处理第i个业务, 另外2个在j,k处. 第一维可以滚动... --------------------------------------------------------- ...