用了几天模拟struts2,最后结果还是很成功的,也基本没有什么遇上比较难解决的问题,万事开头难,在最开始的时候无从下手,看着下面这张struts2工作流程图配合着网上的博客看了一天终于有了眉目。

看到图的时候应该最先看图例:第一个橙色(Servlet Filter)表示过滤器;第二个蓝色的(Struts Core)表示struts2的核心,是struts2最重要的部分;第三个(Interceptors)表示拦截器,是struts2中一个运用的很好的一个地方;最后一个(User created)是用户自己需要书写的代码

struts2的入口是什么?这个问题曾经把我问住了。现在想想如果这张图深深地记住,那么struts2的基本工作流程也就明白了。struts2的入口是过滤器,一个HttpServletRequest进来首先是过滤器,注意是过滤器,在图上我们也可以看到,用户发起的请求首先进入到过滤器,有些时候感觉过滤器是struts2的基础,但是这么说有些绝对,struts2因为有了过滤器,让有些代码变得简单。Struts实际上使用了一个所谓的ServletFilter来“使事情有效”。一般来说,使用Struts
2时不需要编写Servlet。在模拟struts2的时候需要自己定义一个过滤器,自定义的过滤器需要实现Filter接口,在doFilter方法中写入自己定义的规则基本上这个过滤器就可以使用了,注意需要在web.xml文件中进行配置,我们在开发struts2项目的时候也是需要在web.xml文件中配置一下,定义过滤器需要过滤哪些信息,只有经过过滤器选择出来需要进入struts2框架中处理的才会进入,其他的直接跳转到指定页面。自己定义了一个LoginFilter,在下面的配置中需要指定过滤器类,在url-patten中定义过滤的规则,/*代表所有的请求都会过滤。

    <filter>
<filter-name>LoginFilter</filter-name>
<filter-class>com_filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

在过滤器类中是可以执行跳转页面代码的,在上面也说到了在使用struts2的时候不需要编写Servlet,struts2主要是把Servlet隐藏了,Servlet主要是执行了从一个页面到另一个页面的跳转,而过滤器是可以完全代替这些功能的,在过滤器的diFilter方法中声明了ServletRequest和ServletResponse两个类型的参数req、resp,在需要使用跳转的的时候把这两个参数强转成HttpServletRequest和HttpResponse类型的参数即可。在struts2源码中可见:

HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)res;

接着向下,经过过滤器的请求到了ActionMapper,但是ActionMapper只是简单的判断,在上面的过滤器中讲到了判断此时的请求是否过滤掉,这个ActionMapper是判断经过过滤器的请求是否需要struts2处理,也就是判断调用哪个Action。ActionMapper其实是HttpServletRequest和Action调用请求的一个映射,它屏蔽了Action对于Request等javaServlet类的依赖。Struts2中它的默认实现类是DefaultActionMapper。

在struts2的工作流程图中可以看到ActionMapper处理之后又返回给了FilterDispatcher,让FilterDispatcher把请求交给ActionProxy,最终调用还是由ActinProxy调用,注意ActionProxy是一个代理类,这里用到了动态代理这种设计模式,我的关于代理模式的文章:Java设计模式-代理模式,在模拟这里的时候代码,其实动态代理我们接触的很少,代码结构很不熟悉。ActionProxy通过ConfigurationManager读取了struts.xml配置文件,这里就要用到xml解析,通过对xml配置文件的解析,读出数据,包括Action类及做出响应的页面等信息。

ActionProxy通过ActionInvocation来执行用户请求对应Acion的拦截器。ActionInvocation负责管理拦截器(Interceptor)。在拦截器这里又用到了责任链设计模式,详见我的责任链的文章:Java设计模式-责任链模式,关于责任链还是比较好理解的,把不同的处理都放在拦截器中,然后组建成一条链,让用户的请求在这条链上走一遍完成各个不同的处理。

在<interceptors>标签中定义了拦截器类的名字和对应的类

然后在<interceptor-stack>中配置拦截器栈,这里相当于数据结构中的栈,从第一个走到最后,想要返回还要从最后一个依次返回,实际上struts2中调用的拦截器就是这些拦截器栈,用户也可以自己定义拦截器栈,把想要的功能组成一个interceptor-stack

在struts2的源码中struts-default.xml文件中配置了好多拦截器。模拟这里的时候,关于读出Action类,这里主要用到了反射,利用反射对类中的属性赋值及执行方法。

最后的返回的结果HttpServletResponse还是要通过过滤器返回的,在模拟的时候,把一些处理的调用放在了过滤器中这样在返回的时候就可以在过滤器中返回。实际上struts2的类远远不止这些,看到仔细的分析,写出了30多个类。简单的模拟只是实现了表单内容验证登录,很多东西都是写死的。

简单模拟struts2及struts2的处理流程介绍的更多相关文章

  1. springmvc流程 struts2 spring Hibernate 优缺点 使用场景介绍

    为什么使用HandlerAdapter? SpringMVC使用一个Servlet(DispacherServlet)代理所有的请求 , SpringMVC中的处理器是方法级别的处理器,而非类级别的处 ...

  2. SSH(Struts2+Spring+Hibernate)框架搭建流程<注解的方式创建Bean>

    此篇讲的是MyEclipse9工具提供的支持搭建自加包有代码也是相同:用户登录与注册的例子,表字段只有name,password. SSH,xml方式搭建文章链接地址:http://www.cnblo ...

  3. struts2(一) struts2入门

    首先推荐一本书,虽然我还没看过,但是我以后肯定会看的,<Struts+技术内幕>提取密码:kg6w .现在只是停留在会使用struts2的层次,自己也想继续深入研究,但是感觉自己的知识面还 ...

  4. java web学习总结(二十二) -------------------简单模拟SpringMVC

    在Spring MVC中,将一个普通的java类标注上Controller注解之后,再将类中的方法使用RequestMapping注解标注,那么这个普通的java类就够处理Web请求,示例代码如下: ...

  5. WPF简单模拟QQ登录背景动画

    介绍 之所以说是简单模拟,是因为我不知道QQ登录背景动画是怎么实现的.这里是通过一些办法把它简化了,做成了类似的效果 效果图 大体思路 首先把背景看成是一个4行8列的点的阵距,X轴Y轴都是距离70.把 ...

  6. Linux 内核 链表 的简单模拟(2)

    接上一篇Linux 内核 链表 的简单模拟(1) 第五章:Linux内核链表的遍历 /** * list_for_each - iterate over a list * @pos: the & ...

  7. Linux 内核 链表 的简单模拟(1)

    第零章:扯扯淡 出一个有意思的题目:用一个宏定义FIND求一个结构体struct里某个变量相对struc的编移量,如 struct student { int a; //FIND(struct stu ...

  8. JavaWeb学习总结(四十九)——简单模拟Sping MVC

    在Spring MVC中,将一个普通的java类标注上Controller注解之后,再将类中的方法使用RequestMapping注解标注,那么这个普通的java类就够处理Web请求,示例代码如下: ...

  9. 简单模拟Hibernate的主要功能实现

    在学习期间接触到Hibernate框架,这是一款非常优秀的O/R映射框架,大大简化了在开发web项目过程中对数据库的操作.这里就简单模拟其底层的实现. /*******代码部分,及其主要注解***** ...

  10. 【HDU 4452 Running Rabbits】简单模拟

    两只兔子Tom和Jerry在一个n*n的格子区域跑,分别起始于(1,1)和(n,n),有各自的速度speed(格/小时).初始方向dir(E.N.W.S)和左转周期turn(小时/次). 各自每小时往 ...

随机推荐

  1. 校验Linux程序是否被黑客修改

    一个黑客突破你的层层防御后,修改你的程序或者覆盖了你的工具时.确定一个已安装程序的所有文件,有没有被修改过的途径之一就是使用RPM包校验功能 如果图片排版有任何错误,欢迎访问我的简书www.jians ...

  2. Hbase多列范围查找(效率)

    Hbase索引表的结构 Hbase Rowkey 设计 Hbase Filter Hbase二级索引 Hbase索引表的结构 在HBase中,表格的Rowkey按照字典排序,Region按照RowKe ...

  3. Bind、Apply、Call三者的区别

    1)bind与apply.call 的最大区别就是:bind不会立即调用,其他两个会立即调用 var fn = { _int: function(){return 3}, fun: function( ...

  4. 实战DeviceIoControl 之六:访问物理端口

    Q 在NT/2000/XP中,如何读取CMOS数据? Q 在NT/2000/XP中,如何控制speaker发声? Q 在NT/2000/XP中,如何直接访问物理端口? A 看似小小问题,难倒多少好汉! ...

  5. 获取NVIDIA显卡的温度

    NVIDIA显卡在硬件上有温度传感器,可以感知显卡的运行环境.温度数据的获取,一般是通过调用NVIDIA的SDK的相关函数即可.SDK的下载的网址(https://developer.nvidia.c ...

  6. FusionCharts ScrollColumn2D图

    FusionCharts ScrollColumn2D图 1.JSP页面 ScrollColumn2D.jsp: <%@ page language="java" conte ...

  7. html中的块元素和内联元素的区别

    一.定义 块元素一般都从新行开始,它可以容纳内联元素和其他块元素,可设置高度.宽度和边距等. 内联元素一般都是基于语义级的基本元素,它只能容纳文本或其他内联元素,主要特点是:和其他元素位于同一行上,高 ...

  8. CentOS中配置lvm存储

    磁盘添加 vmware workstation 虚拟机为例 1.关闭虚拟机,在虚拟机设置中添加3块硬盘. 2.首先创建物理卷  pvcreate /dev/sdb /dev/sdc Physical ...

  9. ajax就收data的参数

    一,变量 "data": ${cityData},//数据(必传) 二,json data:{"state":"Front"},

  10. Java并发编程-各种锁

    安全性和活跃度通常相互牵制.我们使用锁来保证线程安全,但是滥用锁可能引起锁顺序死锁.类似地,我们使用线程池和信号量来约束资源的使用, 但是缺不能知晓哪些管辖范围内的活动可能形成的资源死锁.Java应用 ...