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

  本文借助动力节点-王勇老师的视频教程中的引例来了解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,实现上面的接口.

  

 1 Action action = null;
 2         if ("/servlet/delUser".equals(path)) {
 3             action = new DelUserAction();
 4         }else if ("/servlet/addUser".equals(path)) {
 5             action = new AddUserAction();
 6         }else if ("/servlet/modifyUser".equals(path)) {
 7             action = new ModifyUserAction();
 8         }else if ("/servlet/queryUser".equals(path)) {
 9             action = new QueryUserAction();
10         }else {
11             throw new RuntimeException("请求失败");
12         }
13         String forward = null;
14         try {
15             forward = action.execute(request, response);
16         } catch (Exception e) {
17             e.printStackTrace();
18         }
19         request.getRequestDispatcher(forward).forward(request, response);

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

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

 1 /
 2            <action-config>
 3                  <action path="/servlet/delUser" type="com.bjpowernode.servlet.DelUserAction">
 4                    <forward name="success">/del_success.jsp</forward>
 5                    <forward name="error">/del_error.jsp</forward>
 6               </action
 7
 8                  <action path="/servlet/addUser" type="com.bjpowernode.servlet.AddUserAction">
 9                    <forward name="success">/add_success.jsp</forward>
10                    <forward name="error">/add_error.jsp</forward>
11               </action
12
13                  <action path="/servlet/modifyUser" type="com.bjpowernode.servlet.ModifyUserAction">
14                    <forward name="success">/modify_success.jsp</forward>
15                    <forward name="error">/modify_error.jsp</forward>
16               </action
17
18                  <action path="/servlet/queryUser" type="com.bjpowernode.servlet.QueryUserAction">
19                    <forward name="success">/query_success.jsp</forward>
20                    <forward name="error">/query_error.jsp</forward>
21               </action
22
23
24            </action-config>

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

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

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

1         /
2            }
3            forwardMap {
4               key="success";
5               value="/del_success.jsp"
6               key="error"
7               value="/del_error.jsp"
8            }
9          /

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

1            Map map = new HashMap();
2            map.put("/servlet/delUser", actionMapping1);
3            map.put("/servlet/addUser", actionMapping2);
4            map.put("/servlet/modifyUser", actionMapping3);
5            map.put("/servlet/queryUser", actionMapping4);
6            

  如果是删除ActionMapping存储如下:  

1            actionMapping {
2                path= "/servlet/delUser";
3             type = "com.bjpowernode.servlet.DelUserAction";
4             forwardMap {
5                 key="success",value="/del_success.jsp"
6                 key="error", value="/del_error.jsp"
7             }
8            }

  三 综合总结

  下面就使用一个例子来总结一下整个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对象,实现业务的处理,然后转向.

转载于:https://www.cnblogs.com/plxx/p/5285476.html

Struts1的实现原理相关推荐

  1. 总结Java常见面试题和答案

    转载自  总结Java常见面试题和答案 int和Integer有什么区别?   答:int是java的原始数据类型,Integer是java为int提供的封装类,java为每个原始数据类型都提供了封装 ...

  2. freemarker的测试结果框架_java必背综合知识点总结(框架篇)

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

  3. java综合知识点总结-必背

    目录 目录 1 基础篇 4 一.JDK常用的包 4 二. Get和Post的区别 4 三. Java多态的具体体现 4 四. StringBuffer StringBuilder String 区别 ...

  4. JAVA超全笔试/面试考试题.(500问)--第三章面试题全面收录

    杂七杂八面试题收录(可能会有重复) 第一,谈谈final, finally, finalize的区别. 第二,Anonymous Inner Class (匿名内部类) 是否可以extends(继承) ...

  5. java面试宝典(综合版)

    目录 目录............................................................................................... ...

  6. Java基础知识点总结(面试版)

    目录 基础篇 4 一.JDK常用的包 4 二. Get和Post的区别 4 三. Java多态的具体体现 4 四. StringBuffer StringBuilder String 区别 5 五. ...

  7. java面试题2019最新

    java面试题 常用 目录 1 基础篇 5 一.JDK常用的包 5 二. Get和Post的区别 5 三. Java多态的具体体现 5 四. StringBuffer StringBuilder St ...

  8. Java面试知识点大全

    知识点复习大纲 目录 1 基础篇 4 一.JDK常用的包 4 二. Get和Post的区别 4 三. Java多态的具体体现 4 四. StringBuffer StringBuilder Strin ...

  9. Java面试整理 -码之狼

    _面试概念整理以及项目逻辑分享 注意:( 所有的概念都是结合所学知识去记忆,死记硬背并不会有太好的记忆并且难以结合到自己的项目中去) 一.JDK常用的包 二. Get和Post的区别 三. Java多 ...

  10. Struts1工作原理

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

最新文章

  1. 神经风格迁移模型综述
  2. Hash MD5 CRC 知识
  3. Android之仿网易V3.5新特性
  4. mysql定义和调用存储过程
  5. PHP中CURL方法curl_setopt()函数的一些参数
  6. 如何查看电脑上是否安装有IIS服务
  7. 机器学习——卷积神经网络计算
  8. 一张图学会python应用到excel-Python应用之------Excel操作
  9. 怎么向前撤回_延迟复工,工资到底怎么算?
  10. html 设计页面,HTML5网页设计
  11. python 中文字符串 编码转换_Python合集之Python字符串编码转换
  12. java实现屏幕截图
  13. c++用msxml6.0解析xml
  14. 使用Jena-TDB存储RDF本体、知识图谱文件
  15. 使用定时任务向百度推送网站URL
  16. 软件架构非功能需求——可靠性
  17. 以史为镜,认知计算机操作系统
  18. 在全民直播的背景下,金融机构做直播带货是必须的吗?
  19. 大数据数据集下载地址
  20. 把一条长为1的线段任意分成三段,则这三段能构成三角形的概率为??

热门文章

  1. 如何在 M1 Mac 上运行英特尔应用程序?
  2. 3D造型软件:Rhino 7 for Mac
  3. 已支持macOS Big Sur 的apple App更新列表
  4. Default Folder X几个小技巧分享
  5. jQuery多文件上传的实例
  6. MySQL innoDB数据插入性能优化
  7. 复制class文件到as中出现非法字符,须要class,interface货enum
  8. laravel路由基本知识
  9. 大道至简第二章-‘是懒人造就了方法’读后感
  10. jquery动态加载js/css文件方法