`
kidiaoer
  • 浏览: 824725 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

Struts1源码分析

阅读更多
struts1是基于当前的一些相关标准的开发技术(servlet,xml…)基础之上,
提供了一个开发框架的开放源码项目。
使用struts1的好处:
  1.良好的架构和设计
  2.可重用,模块化,扩展性好
  3.Open source开源的
  4.它提供了丰富的标签库,使页面能更加灵活的使用。

struts1的缺点:
  1.它太过于依赖web容器,当配置文件改动一次就要重新启动。
  2.它的配置文件太过于复杂。
  3.ActionForm无法进行测试.
  4.Action测试太过于依赖servlet api,所以在测试的时候要用到模拟对象.
 
 
  Struts跟Tomcat、Turbine等诸多Apache项目一样,是开源软件,这是它的一大优点。使开发者
  能更深入的了解其内部实现机制。 Struts开放源码框架的创建是为了使开发者在构建基于Java
  Servlet和JavaServer Pages(JSP)技术的Web应用时更加容易。Struts框架为开放者提供了一个
  统一的标准框架,通过使用Struts作为基础,开发者能够更专注于应用程序的商业逻辑。Struts框
  架本身是使用Java Servlet和JavaServer Pages技术的一种Model-View-Controller(MVC)实现.
具体来讲,Struts的优点有:

    1. 实现MVC模式,结构清晰,使开发者只关注业务逻辑的实现.

MVC即Model-View-Controller的缩写,是一种常用的设计模式。MVC 减弱了业务逻辑
接口和数据接口之间的耦合,以及让视图层更富于变化。Struts 是MVC的一种实现,它
将 Servlet和 JSP 标记(属于 J2EE 规范)用作实现的一部分。Struts继承了MVC的各
项特性,并根据J2EE的特点,做了相应的变化与扩展。

    2. 有丰富的tag可以用 ,Struts的标记库(Taglib),如能灵活动用,则能大大提高开发效率。另外,就
目前国内的JSP开发者而言,除了使用JSP自带的常用标记外,很少开发自己的标记,或许Struts是一个很好的起点。

    3. 页面导航.页面导航将是今后的一个发展方向,事实上,这样做,使系统的脉络更加清晰。通过一
个配置文件,即可把握整个系统各部分之间的联系,这对于后期的维护有着莫大的好处。尤其是当另
一批开发者接手这个项目时,这种优势体现得更加明显。

    4. 提供Exception处理机制 .

    5. 数据库链接池管理

    6. 支持I18N

    缺点:
    一、 转到展示层时,需要配置forward,每一次转到展示层,相信大多数都是直接转到jsp,而涉及
到转向,需要配置forward,如果有十个展示层的jsp,需要配置十次struts,而且还不包括有时候目
录、文件变更,需要重新修改forward,注意,每次修改配置之后,要求重新部署整个项目,而tomcate这
样的服务器,还必须重新启动服务器,如果业务变更复杂频繁的系统,这样的操作简单不可想象。现在就
是这样,几十上百个人同时在线使用我们的系统,大家可以想象一下,我的烦恼有多大。

    二、 Struts 的Action必需是thread-safe方式,它仅仅允许一个实例去处理所有的请求。所以action用
到的所有的资源都必需统一同步,这个就引起了线程安全的问题。

    三、 测试不方便. Struts的每个Action都同Web层耦合在一起,这样它的测试依赖于Web容器,单元测
试也很难实现。不过有一个Junit的扩展工具 Struts TestCase可以实现它的单元测试。

    四、 类型的转换. Struts的FormBean把所有的数据都作为String类型,它可以使用工具Commons-Beanutils进行
类型转化。但它的转化都是在Class级别,而且转化的类型是不可配置的。类型转化时的错误信息返回给用户也是非常困难的。

    五、 对Servlet的依赖性过强. Struts处理Action时必需要依赖ServletRequest 和ServletResponse,所有
它摆脱不了Servlet容器。

    六、 前端表达式语言方面.Struts集成了JSTL,所以它主要使用JSTL的表达式语言来获取数据。可
是JSTL的表达式语言在Collection和索引属性方面处理显得很弱。

    七、 对Action执行的控制困难. Struts创建一个Action,如果想控制它的执行顺序将会非常困难。甚
至你要重新去写Servlet来实现你的这个功能需求。

    八、 对Action 执行前和后的处理. Struts处理Action的时候是基于class的hierarchies,很难
在action处理前和后进行操作。

    九、 对事件支持不够. 在struts中,实际是一个表单Form对应一个Action类(或DispatchAction),换
一句话说:在Struts中实际是一个表单只能对应一个事件,struts这种事件方式称为application
event,application event和component event相比是一种粗粒度的事件。
   
    Struts重要的表单对象ActionForm是一种对象,它代表了一种应用,这个对象中至少包含几个字段,这
些字段是Jsp页面表单中的input字段,因为一个表单对应一个事件,所以,当我们需要将事件粒度细
化到表单中这些字段时,也就是说,一个字段对应一个事件时,单纯使用Struts就不太可能,当然通
过结合JavaScript也是可以转弯实现的。
 
 
sturst1初始化
Struts1 = jsp + servlet + tag   (MVC Model 2)

Struts主要有三个核心的类,分别是ActionServlet,ModuleConfig,RequestProcessor。
ActionServlet就是控制器,
ModuleConfig封装着Struts应用程序的配置信息,
RequestProcessor负责处理每一个HTTP请求。

Struts的核心类就是org.apache.struts.action.ActionServlet,它继承于 javax.servlet.http.HttpServlet,当我
们配置Struts时就要在web.xml文件中配置这个Servlet类。当 ActionServlet初始化时,就调用init()方法。

1.启动 
    加载多个配置文件   ctrl+shift+T(jar)   ctrl+shift+R(源文件resource)  ctrl+O(快速查询方法)
    *init()
        initInternal()读取资源文件(国际化)    初始化Struts框架内在的消息资源,如与系统日志相关的日志、警告和错误消息。
            MessageResources类的getMessageResources()方法
            在getMessageResources()方法中,通过工厂类调配资源文件
                  
        initOther()     由于从form传输过来的都是String类型的值,所以我们要把它们转换成相应的类型。
在这里我们可以学到几个技巧:
技巧一:判断是否是一个Array 类的方法 isArray()
         技巧二:判断type是否是 List的一个父类或者父接口,或者与List为同一个类
         要注意如果List是另一个 primitive的TYPE类,那么type必须也是这个类才会
         返回true,否则都是 false。注意long.TYPE与Long.class是不同的

            查找在web.xml中config参数和convertnull参数的配置
            config默认配置路径为WEB-INF/struts-config.xml (struts1配置文件)  

ActionServlet.initOther()—〉其他初始化
读取web.xml中的config,debug,convertNull的内容。
此方法主要是读取struts-config配置文件和参数convertNull。
convertNull如果convertNull为真时
初始化一个ConvertUtils对象; 由于ConvertUtils.deregister()的初始化,所
有的Converter都是有初始值的,所以这里Struts自己把这些初始值设置为null,即
转换出错的时候返回null,而不是初始值。使用ConvertUtils类的原因是由于从form
传输过来的都是String类型的值,所以我们要把它们转换成相应的类型。目前没有找
到更多有关ConvertUtils的更多信息,如有了解的朋友,可以的话请帮助提供相关信息.多谢!
  这里的”convertNull”是在Struts 1.0里提供的,有的文章中,在这里写的是”debug”而在
  目前,我所使用的web.xml文件里也只有设定。
简单地说就是:如果convertNull为true,在转化从form传输过来的都是String类型的值的时
候,如果出现类型错误就设置为null。


          
        initServlet()
  这个方法主要是通过digester类解析web.xml,对String servletMapping 属性进行初始化。对于
digester说明如下:这是一个基于DOM的SAX实现的类,它是事件触发的,根据xml文件的结 构,
每次读到一个节点元素就会触发一个事件。 它可以直接把xml文件解析为一个java对象。

这是一个比较少见的方法。首先通过this.servletName = getServletConfig().
         getServletName()获取servlet的名称,然后根据
if (servletName.equals(this.servletName)) {
this.servletMapping = urlPattern;
}
来判断当前读到的servlet名称是否是我们运行的servlet的名称,如果是,就把url- pattern作为
我们的servletMapping。


            从web.xml中加载ActionServlet的初始化参数如servlet-name,加载DTD文件并把
            其放入HashMap缓存,读取并解析web.xml的内容,

            另外会将当前的ActionServlet放入到创建的Digester对象的栈中。
              
        initChain()
            读取web.xml中命令链文件初始值chainConfig
            如果没有,则用默认的"org/apache/struts/chain/chain-config.xml"
          
        将当前ActionServlet加入到上下文ServletContext()中
      
        获取ModuleConfig实例,
这个方法使用由initOther()方法获取的config值为要解析的xml路径,用来初始化 ModuleConfig。

Struts中的MessageResource、PlugIn、数据源等,
        都是通过ModuleConfig来实现的;
          
        调用initModuleMessageResources(moduleConfig),用户资源文件的初始化;
      
        调用initModulePlugIns(moduleConfig),用户插件的初始化;
      
        调用initModuleFormBeans(moduleConfig);
            initModuleForwards(moduleConfig);
            initModuleExceptionConfigs(moduleConfig);
            initModuleActions(moduleConfig),
        把struts配置文件中的其他配置存储到servletContext中;
      
        调用moduleConfig.freeze(),固定组件配置;  
          
        通过while循环,解析以"config/"开头的其他struts配置文件,遍历web.xml中
        servletConfig配置的initParameterNames,如发现以"config/" 开始的parameter,
        则根据此值初始化其它的ModuleConfig;   
          
        调用initModulePrefixes(this.getServletContext()) 初始化其他模块并存储
          
        到此,ActionServlet初始化工作就算完成  
          
    附:org.apache.commons的通用组件
            commons-digester  解析XML 是XML文件与对象之间的转化器
            commons-chain     组织复杂流程的处理,是个责任链模式      
          
          
一次请求的流程
    1.以.do结尾的URL被ActionServlet拦截,执行service方法
    2.根据请求传递的方法GET/POST选择执行doGet()或doPost()方法
    3.在doGet()/doPost()方法中,调用process()方法

  在struts1.3.8之前
   是在process()方法中获得RequestProcessor的实例
    5.RequestProcess的实例调用process()方法,处理请求
    6.在RequestProcess类中,创建和验证Form都是在一个方法里面写的,由此我们可以看出它的耦合度非常高。

        首先通过processMultipart()处理请求。
            若传送方法为get,不做处理,直接返回到process()方法
            若传送方法为post,做简单处理后返回process()方法
        其次通过processPath()方法获取path
            若path为null,返回上一层调用
        path不为null,接着进行其它处理
            包括对Locale,Content,NoCache,Preprocess,CachedMessages,Mapping,
            Roles,ActionForm,Populate,Validate,Forward,Include的处理。
          
            然后创建Action实例,并执行Action返回ActionForward,最后处理
            ActionForward。
          
  
   正是由于耦合度非常高,所以就出现了责任链模式,用责任链模式来代替了RequestProcess类。这样的话
            在处理的过程中,采用责任链模式分别由对应的Command类进行处理,
            并随时可能由于异常等原因返回。
在这里我学到了责任链模式对外扩展是开放,对内修改是封闭的。
对外扩展是开放的:如果我们需要加一个新的功能,或者客户需要,我们只要配置一个Command就可以了,而
不用修改源代码。
对内修改是封闭的:比如说要加一个权限,不需要修改它的源代码。或者说改的程度最小。

          
    7.一次请求到此结束,会根据ActionForward执行下一个流程 或 直接转往JSP生成
        HTML发送到浏览器。

通过源码我们可以看出struts1的好处和缺点。

使用struts1的好处:
  1.良好的架构和设计
  2.可重用,模块化,扩展性好
  3.Open source开源的
  4.它提供了丰富的标签库,使页面能更加灵活的使用。

struts1的缺点:
  1.它太过于依赖web容器,当配置文件改动一次就要重新启动。
  2.它的配置文件太过于复杂。
  3.ActionForm无法进行测试.
  4.Action测试太过于依赖servlet api,所以在测试的时候要用到模拟对象.




  
它的一些常识:
    1.它的默认配置名:struts-config.xml.
    2.Action类中最重要的方法: execute().
    3.它的验证方式有两种:在服务器端验证(在FormBean里面重写Validate方法),在客户
端验证(通过配置文件来进行验证)。
    4.在服务器启动时会执行init()来进行初始化一些信息。
    5.它的乱码问题可以通过过滤器来解决。
    6.struts1所需要用到的jar包可能会和tomcat中的jsp-api.jar,servlet-api.jar包冲突,最好
的解决方案是将这两个jar包放到
        重新建的一个包中去,然后再引用这个包中的jar。
    7.在使用validate框架时from类一定要继承ValidatorFrom这个类。
        Struts Validator框架采用两个基于XML的配置文件来配置验证规则。
        这两个文件为validator-rules.xml和validation.xml。
  
struts的标签库的标签主要分为几类:
    1.html标签库   这个标签库的大部分标签和HTML中的标签一一对应的。
                    html标签库的目的是将jsp页面和Action通过ActionForm连接起来。
    2.bean标签库   这个标签库主要用来向客户端输出文本信息(比如说国际化的一些信息等)。
    3.logic标签库  为了避免在JSP页面中直接使用Java代码进行逻辑判断和循环操作.
    4.nested标签库 这个标签库中的标签有来显示form或对象中的“nested”属性
    5.tiles标签库:这个标签库的标签允许我们为视图层建立布局。
  
struts的自定义标签使用过程:
    1.先写一个标签类这个类继承了SimpleTagSupport这个类,实现doTag()方法。
    2.然后再写一个以.tld为后缀的标签库配置文件里面进行配置一些属性包括(标签类、URI等一些东西)
        如果有属性里面还需要添加attribute这个属性。
    3.在页面上通过<%@taglib uri="" prefix="" %>导入标签库 使用的时候注意前缀和在.tld中配置的标签名及属性
  
struts1中DynaValidatorForm的使用
        <form-beans>
                <form-bean name="LoginForm" type="org.apache.struts.validator.DynaValidatorForm">
                        <form-property name="userName" type="java.lang.String" />
                        <form-property name="password" type="java.lang.String" />
                </form-bean>
        </form-beans>
        如果在Action类中使用它,可以这样子:DynaValidatorForm loginForm=(DynaValidatorForm)form;
  
客户端数据验证与服务端数据验证的区别:
Struts中客户端验证跟服务器端验证有区别.客户端验证直接写一个action文件便可实现,
而服务器端验证必须通过客户端程序去调用服务器端相应的 WebServices,实现业务逻辑.
它们的本质区别是,就是客户端数据校验是在客户端上进行的,而服务器端校验是在服务器上进行的,
在速度上客户端要快很多,但也有缺陷,就是当有黑客攻击的时候,他完全可以绕过客户端直接和服务器交互。
我看到过有人介绍这方面的知识时说,一个有经验的黑客至少能有100种以上的方法绕过客户端之间访问服务器,
而且服务器如果是用JDBC写的话,还要防止sql的注入。不然很容易让黑客攻击。
1、如果注册的时候输入了密码它还显示在页面的话,就用redisplay在输入框不显示它。
2、如果试用框架验证继承ValidatorForm的话,不需要验证的类就可以在action配置里面加个Validator属性="false";
  
分享到:
评论

相关推荐

    struts 1 源码分析

    下面我们将深入探讨Struts 1的源码分析,特别是针对Struts 1.2版本。 1. **架构概述** - **DispatcherServlet**:作为Struts的核心,DispatcherServlet负责接收HTTP请求并分发到相应的Action。 - **ActionMapping...

    struts2 源码分析

    Struts2 源码分析 Struts2 是一个基于MVC 模式的Web 应用程序框架,它的源码分析可以帮助我们更好地理解框架的内部机制和工作流程。下面是Struts2 源码分析的相关知识点: 1. Struts2 架构图 Struts2 的架构图...

    struts2源码分析

    struts2源码详细解析51CTO下载-struts2源代码分析(个人觉得非常经典)

    struts2源码分析总结

    本文将深入探讨Struts2的源码分析,特别是关于StrutsPrepareAndExecuteFilter的初始化过程,这是Struts2的核心组件之一,负责处理HTTP请求。 首先,我们来看`StrutsPrepareAndExecuteFilter`的初始化。这个过滤器...

    Struts2源码分析

    在深入理解Struts2的工作原理时,源码分析是必不可少的步骤。Struts2的核心设计理念和设计模式相比Struts1.x有了显著的变化,这使得它成为一个独立且成熟的框架。 首先,Struts2的架构基于WebWork的核心,这意味着...

    struts2部分源码分析

    本篇文章将深入探讨Struts2的运行原理,通过源码分析来揭示其内部工作机制。 首先,我们从核心组件开始。Struts2的核心组件包括Action、FilterDispatcher、Interceptor和Result。Action是业务逻辑的载体,它接收...

    Struts2源码阅读

    通过阅读Struts2的源码,我们可以深入了解框架如何处理请求、如何调度Action以及如何应用拦截器来扩展功能。这有助于开发者更好地定制和优化他们的应用程序,提高代码质量和性能。在实际开发中,对源码的理解能帮助...

    struts1.2源码研究

    Struts 1.2 是一款基于 Model-View-Controller(MVC)设计模式的开源Java Web框架,由Apache...通过深入理解Struts 1.2的源码,开发者可以更好地利用这个框架,解决实际项目中的问题,同时为自定义扩展和优化提供可能。

    struts2 源码解读

    源码分析是提升编程技能和解决问题的关键,特别是对于复杂的框架如Struts2,理解其内部工作原理能够帮助我们优化应用性能,修复潜在问题,并进行定制化开发。 首先,Struts2的核心组件包括Action、Result、...

    Struts2源码分析--请求处理.pdf

    Struts2源码分析--请求处理.pdf

    struts2框架源码

    了解这些基本概念后,深入源码分析可以发现以下关键技术点: 1. **Dispatcher Servlet**:Struts2的核心控制器,负责接收HTTP请求,通过ActionMapper找到对应的Action,然后调用ActionInvocation进行拦截器链的执行...

    Struts2源码分析--请求处理[汇编].pdf

    Struts2源码分析--请求处理[汇编].pdf

    struts 2 源码 导入eclipse工程

    1. 下载Struts 2的源码包,通常可以从Apache官方网站获取最新版本。 2. 打开Eclipse,选择“File” -&gt; “Import”,在弹出的对话框中选择“Existing Projects into Workspace”。 3. 在“Select root directory”中...

    struts2框架源码分析及问题汇总

    本文将深入剖析Struts2的源码,揭示其工作原理,并汇总常见问题,帮助开发者更好地理解和使用这个框架。 一、Struts2框架基础 1. 框架结构:Struts2的核心组件包括Action、Result、Interceptor(拦截器)等。...

    struts-1.3.9 源码

    通过分析Struts 1.3.9的源码,开发者可以学习到如何设计一个MVC框架,了解其请求处理流程、视图渲染机制以及如何通过配置文件定制行为。此外,这也有助于开发者在遇到问题时能够追溯源代码,找到问题的根源,或者为...

    struts1源码下载

    在Struts1的源码中,我们可以深入理解其工作原理,包括以下核心组件和概念: 1. **ActionServlet**:这是Struts1的核心控制器,负责拦截所有到达Servlet容器的HTTP请求,并根据配置信息将请求分发到相应的Action。 ...

    struts2源代码分析

    Struts2是Struts1.x和WebWork社区合并的产物,可以看作是WebWork的增强版,具备稳定性、高性能和成熟的设计。尽管Struts2试图保持与Struts1.x的兼容性,但其实现方式和工作流程已经发生了根本变化。 Struts2的核心...

Global site tag (gtag.js) - Google Analytics