`
1250605829
  • 浏览: 60509 次
  • 性别: Icon_minigender_1
  • 来自: 阜阳
社区版块
存档分类
最新评论

回忆 struts1/2

    博客分类:
  • java
阅读更多
struts1 与  struts2的对比。

action类:
struts1要求action类继承一个抽象类。所以说struts1使用抽象类编程而不是接口。
struts2 action类可以实现一个action接口,也可以实现其他接口,struts2提供了一个actionSupport基类去实现常用的接口。action接口不是必须的,任何有execute标识的pojo对象都可以作为struts对象。

线程模式:
struts1 action是单例模式并且必须线程安全  因为仅有action的一个实例来处理所有的请求,单例策略限制了struts1 action能做的事,并且在开发时特别小心。action资源是线程安全和或同步的。
struts2 action对象为每一个请求产生一个实例,因此没有线程安全问题(servlet容器给每个请求产生许多可丢弃的对象,并且不会导致性能和垃圾回收问题)
servlet 依赖:
struts1 action依赖于servletApi , 因为一个action被调用的时候 HttpServletRequest和HttpServletResponse被传递给execute方法
struts2 action不依赖于容器,允许action脱离容器单独被测试。如果需要 action仍然可以访问舒适的request和response。但是其他的元素减少或者消除直接这两个对象的必要性。(额。。?奇怪的说,消除了直接访问的必要性?记得每次对前台传过来的参数信息进行转码的时候就要定义HttpRequestSponse进行转码呀- -。有啥方法不需要用么。)
可测性:
测试struts1 action的一个主要问题是execute方法暴漏了servletApi  所以要依赖servletAPI
struts2 action可以通过初始化 设置属性 使用方法来测试。而且依赖注入的支持也使测试更容易方便
捕获输入:
struts1 使用actionForm对象捕获输入,所有的actionform必须继承一个基类.因为其他javaBean不能用作actionForm,貌似是说struts1也可以动态设置Bean但是这样会创建已经存在的javaBean.
struts2  直接使用Action属性作为输入属性.消除了对第二个输入对象的需求.这个灰常方便的说.struts2也支持actionform模式.rich对象类型.
表达式语言:
struts1 整合了jstl,因此使用jstl el。但是对集合跟索引属性的支持很弱。
struts2可以使用jstl,同时支持一个更强大和灵活的表达式语言。(OGNL   关于该el标签,很好的例子:http://www.iteye.com/topic/646851)
Action执行的控制:
Struts1支持每一个模块有单独的Request Processors(生命周期),但是模块中的所有Action必须共享相同的生命周期。
Struts2支持通过拦截器堆栈(Interceptor Stacks)为每一个Action创建不同的生命周期。堆栈能够根据需要和不同的Action一起使用


关于struts1/2的流程:

struts1本质上其实就是一个servlet+jsp+自定义tag+javaBean   核心控制器就是一个servlet
流程:
服务器启动容器将actionServlet装载进虚拟机并实例化--->调用init()方法--->初始化页面的国际化以及额外配置---->初始化ActionServlet  是通过用digester去解析web.xml并把web.xml里面的属性封装成java对象 并封装到ActionServlet.


   web.xml(用流)                                ActionServlet
         |                                                       |
         |                                                       |
  parse(input)<-----------digester--------->push(object)
         |                                                       |
         |                                                       |
     xml------------------------------------>java object然后初始化链(initChain):首先检查用户有没有在web.xml配置chainConfig,如果没有就用默认的
org.apache.struts.chain.chain-config.xml文件,然后用digester去解析这个文件。并初始化struts1的处理类。
接着就是初始化moduleConfig:主要是用digester去解析struts-config.xml文件,并把这个文件里面的一些属性一Java 对象的形式封装到ModuleConfig。然后初始化 initModuleMessageResources(moduleConfig);
            initModulePlugIns(moduleConfig);
            initModuleFormBeans(moduleConfig);
            initModuleForwards(moduleConfig);
            initModuleExceptionConfigs(moduleConfig);
            initModuleActions(moduleConfig);
           
           
           
    Struts2的核心是拦截器,而且是面向切面思想实现(AOP)
    struts2的核心控制器本质是个过滤器,所以要遵循servlet的规范。当web服务器加载的时候 调用web.xml配置的struts2的过滤器的init方法,在init方法中创建daspatcher对象
    然后Daspatcher调用自己的init方法。然后正式开始struts真正的初始化、struts为每个配置文件都提供一个处理类。(属性文件有属性文件的处理类,xml文件有xml文件的处理类,客户配置的文件也有客户配置文件的处理类)
    这也体现了struts2的多线程处理机制以及策略模式
    然后把这些处理类全部封装到configurationManager中。创建一个容器,把Daspatcher注入容器中。
   
进入doFilter方法
首先设计编码,默认为UTF-8(因为UTF-8是国际通用的)所以在用struts2写项目的时候不需要转码。接着创建一个ActionContext(首先构造一个ValueStack其实是OgnlValueStack,然后将request、session、ServletContext等用相应的map集合封装起来,然后把这些封装的map对象用另一个map封装,这样就达到了与servlet的解耦,接着声明一个attr map集合,将request、session、servletContext所相应的map集合封装起来,这就是为什么attr的map可以实现在request、session、application中轮询值的原因。最后将attr的map集合放进那个上面另一个map中,再把这个map放到ActionContext中)。再创建一个ActionMapping,它是通过ActionMapper来指定的。(ActionMapper是用来决定是不是要调用一个Action来处理这个请求)。再接着创建ActionProxy(ActionProxy通过ConfigurationManager询问框架的配置的文件找到需要调用的Action类)接着创建AcitonInvocation实例,同时ActionInvocation通过代理模式调用Action,在调用Aciton之前根据配置加载Action相关的所以Interceptor(把这些拦截器以栈的形式,进行调用),最后返回结果result.


最后补充一个对servler的理解:

简单的说,servlet就JAVA处理WEB请求的一种机制。可以担当客户请求与服务器响应的中间层。server是位于web服务器内部的服务器端的java应用程序。
servlet工作模式:
客户发送请求到服务器-->服务器启动并调用servlet servlet根据客户端请求生成响应内容并传给服务器-->服务器响应返回客户端
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics