`
javabkb
  • 浏览: 53570 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

对sturts2的进一步理解

阅读更多
    当初学struts2框架的时候觉得学得还行,也一直用它做项目.但是最近又把struts2的知识点拉了一遍,上网看了看关于它的帖子,才发现struts2原来是这个样子。
     于是就根据网上的内容和部分自己的理解做了个整合,做一个笔记。
     一.Struts2怎么处理一个用户请求的?
     1,首先用户发出一个请求,通过filterDispatcher拦截器拦截下来。
     2, filterDispatcher会询问ActionMapper来决定这个请求是否需要调用某个Action。
     3, 这个ActionMapper封装了请求的信息。如果ActionMapper决定需要调用某个Action,FilterDispatcher会按信息(action的名字,调用的方法名)创建一个Action的代理对象。实际上对Action的调用就是通过这个代理对象来实现的。
     4,把请求交给这个代理,如果用户提交的请求没有指定方法,那么Struts2则默认excute方法。这个代理会创建一个调度器的实例。
     这个调度器里面定义了一个invoke方法,这个方法就实现了拦截器的交互和执行Action里的excute方法。
     5, 拦截器是以value栈的形式调用。
      Struts2默认的有18个拦截器。第一个拦截器是一个异常拦截器,这样的话,我第一个拦截器把异常捕获到,那么以后就不用捕获其他拦截器出现的异常了。
    6, 当Action执行完以后,调度器就会负责根据struts.xml中的配置找到对应的返回结果。
     7, 然后调度器就返回所有的拦截器,通过response把结果集返回给客户。
二,Struts2和Struts1的不同
  Action 类:
  Struts1要求Action类继承一个抽象基类。Struts1的一个普遍问题是使用抽象类编程而不是接口。
  Struts 2 Action类可以实现一个Action接口,也可实现其他接口,使可选和定制的服务成为可能。Struts2提供一个ActionSupport基类去实现 常用的接口。Action接口不是必须的,任何有execute标识的POJO对象都可以用作Struts2的Action对象。
  线程模式:
  Struts1 Action是单例模式并且必须是线程安全的,因为仅有Action的一个实例来处理所有的请求。单例策略限制了Struts1 Action能做的事,并且要在开发时特别小心。Action资源必须是线程安全的或同步的。
  Struts2 Action对象为每一个请求产生一个实例,因此没有线程安全问题。(实际上,servlet容器给每个请求产生许多可丢弃的对象,并且不会导致性能和垃圾回收问题)
  Servlet 依赖:
  Struts1 Action 依赖于Servlet API ,因为当一个Action被调用时HttpServletRequest 和 HttpServletResponse 被传递给execute方法。
  Struts 2 Action不依赖于容器,允许Action脱离容器单独被测试。如果需要,Struts2 Action仍然可以访问初始的request和response。但是,其他的元素减少或者消除了直接访问HttpServetRequest 和 HttpServletResponse的必要性。
  可测性:
  测试Struts1 Action的一个主要问题是execute方法暴露了servlet API(这使得测试要依赖于容器)。一个第三方扩展--Struts TestCase--提供了一套Struts1的模拟对象(来进行测试)。
  Struts 2 Action可以通过初始化、设置属性、调用方法来测试,“依赖注入”支持也使测试更容易。
  捕获输入:
  Struts1 使用ActionForm对象捕获输入。所有的ActionForm必须继承一个基类。因为其他JavaBean不能用作ActionForm,开发者经常创建多余的类捕获输入。动态Bean(DynaBeans)可以作为创建传统ActionForm的选择,但是,开发者可能是在重新描述(创建)已经存在的JavaBean(仍然会导致有冗余的javabean)。
   Struts 2直接使用Action属性作为输入属性,消除了对第二个输入对象的需求。输入属性可能是有自己(子)属性的rich对象类型。Action属性能够通过web页面上的taglibs访问。Struts2也支持ActionForm模式。rich对象类型,包括业务对象,能够用作输入/输出对象。这种ModelDriven 特性简化了taglib对POJO输入对象的引用。
  表达式语言:
  Struts1 整合了JSTL,因此使用JSTL EL。这种EL有基本对象图遍历,但是对集合和索引属性的支持很弱。
  Struts2可以使用JSTL,但是也支持一个更强大和灵活的表达式语言--”Object Graph Notation Language” (OGNL).
  绑定值到页面(view):
  Struts 1使用标准JSP机制把对象绑定到页面中来访问。
  Struts 2 使用 “ValueStack”技术,使taglib能够访问值而不需要把你的页面(view)和对象绑定起来。ValueStack策略允许通过一系列名称相同但类型不同的属性重用页面(view)。
  类型转换:
  Struts 1 ActionForm 属性通常都是String类型。Struts1使用Commons-Beanutils进行类型转换。每个类一个转换器,对每一个实例来说是不可配置的。
  Struts2 使用OGNL进行类型转换。提供基本和常用对象的转换器。
  校验:
  Struts 1支持在ActionForm的validate方法中手动校验,或者通过Commons Validator的扩展来校验。同一个类可以有不同的校验内容,但不能校验子对象。
  Struts2支持通过validate方法和XWork校验框架来进行校验。XWork校验框架使用为属性类类型定义的校验和内容校验,来支持chain校验子属性
  Action执行的控制:
  Struts1支持每一个模块有单独的Request Processors(生命周期),但是模块中的所有Action必须共享相同的生命周期。
  Struts2支持通过拦截器堆栈(Interceptor Stacks)为每一个Action创建不同的生命周期。堆栈能够根据需要和不同的Action一起使用。
三,Struts2框架按如下搜索顺序加载Struts2常量:
struts-default.xml     保存在struts2-core-版本.jar
struts-plugin.xml      保存在struts2-Xxx-版本.jar
struts.xml                  web应用默认的Struts2配置文件
struts.properties       web应用默认的Struts2配置文件
web.xml                    web应用的配置文件
如果在多个文件配置了同一个Struts2常量,则后一个文件中配置的常量值会覆盖前面文件中配置的常量。
四,struts2遇到类型转换错误的时候,struts2自动生成一条错误信息,并且自动将这条错误信息放到addFieldError里面
五, 在这里,或许有些读者会提出问题来,为什么好好的Servlet对象要在这里被封装成Map对象呢?我想原因可能有以下两个:
1. 对Struts2的Action彻底屏蔽Servlet容器,从而无需再使用底层Servlet API进行编程。你所面对的,将永远是一个又一个的Java对象。
2. 便于各种View技术,例如JSP,Freemarker,Velocity等对ValueStack中上下文环境,尤其是Servlet对象中的数据进行读取。试想,如果在这里不将HttpServletRequest,HttpSession等Servlet对象转化成Map,那么我们将很难通过OGNL表达式,对这些Servlet对象中的值进行读取。
六,验证validate     先执行validateMethod方法  再执行validate方法  execute方法 validateExecute()
七,字段校验(常用)和非字段校验  
   客户端的校验:1.form的主题(theme)一定不能设定为simple
               2,将form的validate属性设置为true
   最好不要使用struts2给我们提供的客户端校验方法
八,fieldError
1,真正存放在field级别错误的信息对象是LinkdedHashMp
2,该LinkedHashMap的key是String类型的,value是ArrayList类型的
   3,对于Action级别的错误信息,实际上是放置在ArrayList中的
九,拦截器  拦截器栈
    我们可以把struts2想象成一个容器,配置了许多拦截器,然后一层一层地调用
     <interceptor-ref></interceptor-ref>
     <interceptor-ref name=”defaultStack”></interceptor-ref>
     先配的拦截器先执行,先配置的后出来(进门出门)
     <include>优先级高于<exclude>
十,模型驱动
paramsPrepareParamsStack在Struts 2.0中是一个很奇妙的interceptor stack,以至于很多人疑问为何不将其设置为默认的interceptor stack。paramsPrepareParamsStack主要解决了ModelDriven和Preparable的配合问题,从字面上理解来说,这个stack的拦截器调用的顺序为:首先params,然后prepare,接下来modelDriven,最后再params。Struts 2.0的设计上要求modelDriven在params之前调用,而业务中prepare要负责准备model,准备model又需要参数,这就需要在 prepare之前运行params拦截器设置相关参数,这个也就是创建paramsPrepareParamsStack的原因。流程如下:
     1. params拦截器首先给action中的相关参数赋值,如id
     2. prepare拦截器执行prepare方法,prepare方法中会根据参数,如id,去调用业务逻辑,设置model对象
     3. modelDriven拦截器将model对象压入value stack,这里的model对象就是在prepare中创建的
     4. params拦截器再将参数赋值给model对象
     5. action的业务逻辑执行 依据此stack
十一,sturts2与Servlet耦合部分
   (1)ActonContext.getContext()   (将request,session等转化为map,方便测试,但是没有httpresponse的接口)
   (2)ServletResponseAware,ServletRequestAware接口分别实现setServletResponse()方法,servletResquest()方法
   Struts2框架自动将与容器相关的request对象自动set到应用里面去,这是一个典型的IOC
   (3)ServletActionContext 直接静态方法调用,即可拿到request等对象
   建议使用第一种,因为虽然与servlet耦合,但是并没有真正出现servletAPI,整个action还是很干净的,如果想使用httpresponse,那么可以使用第三种方式。
分享到:
评论
1 楼 轻于鸿毛 2012-03-31  

初学者受教了

相关推荐

    深入浅出struts2

    开发人员还可以通过拦截器(可以自定义拦截器或者使用Struts2提供的拦截器)来对请求进行预处理和后处理,这样一来,处理请求就变得更加模块化,从而进一步减小耦合度。模块化是一个通用的主题——可以通过插件机制...

    青鸟搜藏.(一个基于struts的b/s项目)

    青鸟搜藏项目,该项目是基于b/s结构的网站,是基于struts的网站,他包括列表显示,添加和云图显示等功能,通过了解该项目进一步理解多对多的应用。

    java web技术开发大全(最全最新)

    《Java Web开发技术大全:JSP+Servlet+Struts+Hibernate+Spring+Ajax》特别介绍了Struts 2对AjAX的支持,还重点剖析了SSH框架的整合开发,并给出了两个综合案例来展示整合SSH框架开发Web应用。 和已经出版的同类图书...

    java web开发技术大全

    《Java Web开发技术大全:JSP+Servlet+Struts+Hibernate+Spring+Ajax》特别介绍了Struts 2对AjAX的支持,还重点剖析了SSH框架的整合开发,并给出了两个综合案例来展示整合SSH框架开发Web应用。 和已经出版的同类图书...

    在线图书网站的构建

    在本课程的实验中,通过使用JSP/Servlet/JDBC/Struts框架技术构建一个具有基本功能的在线图书网站,使学生进一步理解和掌握Web应用的开发技术。主要要求如下:  1. 掌握JSP/Servlets﹑Struts框架等基本的Web开发...

    leetcode下载-java-rookie:新手入门Java

    引用另一个fork的项目swagger-demo-struts2里的想法,我可以去研究一下struts2-swagger和struts2-restful这方面,然后框架学习主攻springboot吧,进一步把前后端分离开 虽然我这个菜鸟说重构可能没人听(这才是重点

    java软件培训实习报告..doc

    四、实习内容概要 应用 java 基础、 MySQL 数据库、 Servlet 技术、 JSP 页面设计、 JQuery 、 ajax 、 hibernate 、 struts2、 spring 、 xml 等技术完成网站后台的开发。 五、实习内容 5.1 java基础知识 Java 的...

    JAVA软件培训实习报告.pdf

    四、实习内容概要 应用 java 基础、MySQL 数据库、Servlet 技术、JSP 页面设计、JQuery、ajax、hibernate、 struts2、spring、xml 等技术完成网站后台的开发。 五、实习内容 5.1 java 基础知识 Java 的基础知识对于...

    java软件工程师顶岗实习报告.doc

    主要应用java基础、My SQL数据库、Servlet技术、JSP页面设计、JQuery、ajax、maven、freemarket、hibern ate、struts2、spring、xml等技术完成网站与游戏后台的开发 四、实习安排 第一阶段:linux 第二阶段:java...

    部分印度医学研究机构的研究成果(2007-2011)-研究论文

    研究是任何学科领域的Struts,不仅需要对其生存和维持,而且还需要进一步扩大学科范围。 在任何级别进行的大多数研究活动都旨在首先考虑生物和人类的福利和改善。 医学研究一直是人类的至高梦想,因为它直接关系到...

    java初学者的工具ppt文件

    初学Java,不建议用IDE工具,通过一行行的敲代码,你会碰到很多问题,只有这样,你才能学会怎样解决问题,并加深自己对Java的理解。 准备好后,开始进入激动人心的Java学习里程吧! 3. Java基础学习之路 学习Java的...

    UML和模式应用(架构师必备).part01.rar

    第40章 迭代式开发和敏捷项目管理的进一步讨论 40.1 如何计划一次迭代 40.2 适应性计划与预测性计划 40.3 阶段计划和迭代计划 40.4 如何使用用例和场景来计划迭代 40.5 早期预算的有效性(无效性) 40.6 将...

    UML和模式应用(架构师必备).part07.rar

    第40章 迭代式开发和敏捷项目管理的进一步讨论 40.1 如何计划一次迭代 40.2 适应性计划与预测性计划 40.3 阶段计划和迭代计划 40.4 如何使用用例和场景来计划迭代 40.5 早期预算的有效性(无效性) 40.6 将...

    UML和模式应用(架构师必备).part02.rar

    第40章 迭代式开发和敏捷项目管理的进一步讨论 40.1 如何计划一次迭代 40.2 适应性计划与预测性计划 40.3 阶段计划和迭代计划 40.4 如何使用用例和场景来计划迭代 40.5 早期预算的有效性(无效性) 40.6 将...

    UML和模式应用(架构师必备).part06.rar

    第40章 迭代式开发和敏捷项目管理的进一步讨论 40.1 如何计划一次迭代 40.2 适应性计划与预测性计划 40.3 阶段计划和迭代计划 40.4 如何使用用例和场景来计划迭代 40.5 早期预算的有效性(无效性) 40.6 将...

    UML和模式应用(架构师必备).part03.rar

    第40章 迭代式开发和敏捷项目管理的进一步讨论 40.1 如何计划一次迭代 40.2 适应性计划与预测性计划 40.3 阶段计划和迭代计划 40.4 如何使用用例和场景来计划迭代 40.5 早期预算的有效性(无效性) 40.6 将...

    UML和模式应用(架构师必备).part04.rar

    第40章 迭代式开发和敏捷项目管理的进一步讨论 40.1 如何计划一次迭代 40.2 适应性计划与预测性计划 40.3 阶段计划和迭代计划 40.4 如何使用用例和场景来计划迭代 40.5 早期预算的有效性(无效性) 40.6 将...

    UML和模式应用(架构师必备).part08.rar

    第40章 迭代式开发和敏捷项目管理的进一步讨论 40.1 如何计划一次迭代 40.2 适应性计划与预测性计划 40.3 阶段计划和迭代计划 40.4 如何使用用例和场景来计划迭代 40.5 早期预算的有效性(无效性) 40.6 将...

    UML和模式应用(架构师必备).part05.rar

    第40章 迭代式开发和敏捷项目管理的进一步讨论 40.1 如何计划一次迭代 40.2 适应性计划与预测性计划 40.3 阶段计划和迭代计划 40.4 如何使用用例和场景来计划迭代 40.5 早期预算的有效性(无效性) 40.6 将...

Global site tag (gtag.js) - Google Analytics