【Struts2.0】Struts 应用转移到 Struts 2 (一)

   有很多人都很熟悉 Struts, 无论是从项目中直接获得的实战经验还是从书中了解到的。我们这一系列文章,将通过一个由 Stuts 转移到 Struts2 简单的例子向大家展现Struts2的所有特征。
    在我们开始这个例子之前,你需要去知道一点 Struts2的背景知识。在第一部分的文章中,我们将介绍Struts2与Struts的核心框架的不同点,以助于更好地了解其他方面的整合。第二部分中,我们将深入探讨 actions 的差别, action相关的框架特征,和action配置。在最后一部分中,我们将会讲述 user interface,我们也会讲到其架构,UI构件,themes 和标签。 还有如何为你的应用加上新的外观。
    我们并不打算谈及迁移过程的所有细节方面,我们只是从出发点开始介绍Struts2 的概念和现在可用的所有特征。但拥有这些知识,你将在以后Struts2的应用中无往而不利。
   
Struts的历史
    Struts的第一个版本 是在 2001年5月份发布。它提供了一个Web应用的解决方案,如何让 JSPs 和 servlets 共存去提供清晰的分离视图和业务和应用逻辑的架构。在Struts之前,最通常的做法是在JSP中加入业务和应用逻辑,或者在servlets中生成视图。
    自从第一个版本的发布, Struts 实际上已成为业界公认的Web应用标准。但随着时间的推移,Web应用框架经常变化的需求,产生了几个下一代 Struts的解决方案。其中两个可选方案是Shale 和 Struts Ti。 Shale 是一个基于构建的框架,并在最近成为 Apache 中的重要项目。而 Struts Ti 则是继续坚持 MVC模式的基础上改进,继续Struts的成功经验。
    WebWork项目是在2002年3月发布的,它对Struts式框架进行了革命性改进,引进了不少新的思想,概念和功能,但和原Struts代码并不兼容。WebWork是一个成熟的框架,经过了好几次重大的改进与发布。在2005年12月,WebWork与Struts Ti决定合拼, 再此同时, Struts Ti 改名为 Struts Action Framework 2.0,成为Struts真正的下一代。

请求如何运作
    在我们开始详细探讨如何转移Struts到Struts2之前,让我们来看看整个请求流程在新架构中是如何运作的。你会注意到在整个请求的生命周期,仍是以controller作主体,而且所有的概念还都是你以前所熟悉的, 就如:

  • 通过URL请求的参数来调用Actions来把数据传给server.
  • 所有的Servlet objects (request, response, session,之类.) 仍然可以在Action中获取
    下图展示了整个请求的概要过程:


    整个请求过程可以分为六步骤:
    1. 一个请求产生并经由框架处理 - 框架根据请求匹配相应的配置,如使用哪些拦截器,action 类和结果。
    2. 请求通过一系列的拦截器 - 拦截器,和拦截器组经配置后,能处理不同等级的请求,它们为请求提供了各种预处理,切面处理。这和Struts的使用 Jakarta Commons Chain 构件的 RequestProcessor类很相似。
    3. 调用 Action - 产生一个新的action对象实例,并提供请求所调用的处理逻辑的方法。Struts2 可以在配置action时为请求分配其指定的方法。我们在第二部文章中将对这步骤进行进一步讨论;
    4. 调用产生的结果 - 获取通过action的方法处理后返回来的结果,匹配其result class并调用产生的实例。有种情况是在UI模板去生成HTML时才去处理这些结果。如果在这种情况下,在Struts2 模板中的tags能直接返回到 action 中,取结果来呈现界面。 
    5. 请求再次经过一系列的拦截器处理后返回 - 请求反顺序通过与原来进入时的拦截器链, 当然,你也可以配置在这个过程中减少或增加拦截器处理.
    6. 请求返回到用户 - 最后一步是由 control 返回到servlet。通常是生成HTML返回到user, 但你也可以指定返回的HTTP头或HTTP重定向。
      你应该已注意到,Struts2与Struts的差别。最明显的就是Struts2是pull-MVC 架构,就是可以直接从Action中获取所需要的数据,而不是像Struts那样必须把 beans 存到page, request,或者session中才能获取。这个我们将在下一章中详细提及。

      配置框架
      首先最重要的是,让框架能通过web.xml在servlet containers里运行。
      下面这个就是大家都熟悉的 Struts在 web.xml里的配置方法
         
         < servlet >
              
      < servlet-name > action </ servlet-name >
              
      < servlet-class > org.apache.struts.action.ActionServlet </ servlet-class >
              
      < init-param >
                  
      < param-name > config </ param-name >
                  
      < param-value > /WEB-INF/struts-config.xml </ param-value >
              
      </ init-param >
              
      < load-on-startup > 2 </ load-on-startup >
          
      </ servlet >

          
      < servlet-mapping >
              
      < servlet-name > action </ servlet-name >
              
      < url-pattern > *.do </ url-pattern >
          
      </ servlet-mapping >

      在 Struts2 中,这个有少许改变,最明显的是dispatcher 由servlet转为servlet filter, 其配置和servlet一样简单,如下:
         
        < filter >
               
      < filter-name > webwork </ filter-name >
                 
      < filter-class >
                  org.apache.struts.action2.dispatcher.FilterDispatcher
         
      </ filter-class >
          
      </ filter >

          
      < filter-mapping >
         
      < filter-name > webwork </ filter-name >
         
      < url-pattern > /* </ url-pattern >
          
      </ filter-mapping >

      和servlet配置一样,filter配置定义了名称(供关联)和filter的类。filter mapping让URI匹配成功的的请求调用该filter。默认情况下,扩展名为".action"。
      这个是在default.properties文件里的"struts.action.extension" 属性定义的。
      工具箱:  "default.properties"是配置选项定义文件。通过在classpath中包含一个叫"struts.properties"的文件,并设置不同的属性值,你可以覆盖这个默认的配置,实现自己的配置。
      对于Struts, servlet配置提供了初始化tag的参数和使用的文件,而Struts2没有这样的配置参数,取而代之的是在classpath下的默认配置文件"struts.xml"。
      工具箱/提示:  Struts actions(扩展名".do"),Struts2 actions(扩展名".action"),所以Struts和Struts2可以在一个系统中共存。所以最好是保持原先的系统,在新功能的开发上用 Struts2, 如果时间和资源允许的情况下再逐步迁移。另一种方法是只是把Struts2的扩展名改为".do",可重用JSPs.
      分析Actions
      在上面介绍的请求运作流程中,我们谈及了一些Struts和Struts2的不同点。现在我们将较深入地探讨这两个框架中action结构的具体差别。
      让我们来回顾一下 Struts 的 action 结构, 主要的形式如下:
      public   class  MyAction  extends  Action  {
          
      public ActionForward execute(ActionMapping mapping,
                                       ActionForm form,
                                       HttpServletRequest request,
                                       HttpServletResponse response)
                  
      throws Exception {
              
      // do the work
              return (mapping.findForward("success"));
          }

      }

      当实现一个Struts action时, 你需要注意一下问题:
      1. 所有的action 都必须继承于base Action 类.
      2. 所有的action都必须是线程安全的,因为action是单例的,singleton的.
      3. 因为所有的action都必须是线程安全的,所以所有的对象都不能是类属性, 都必须以方法参数的形式传值。
      4. 调用action的方法必须命名为 "execute" ( 在Struts中的  DispatchAction 类好像可以用其它方法去执行同一个action ,但实际上在框架中调用的仍然是 "execute" 方法。).
      5. ActionForward 的结果是通过ActionMapping 类中的方法来产生的,通常是"findForward"方法.
        相比较之下, Struts2的action 提供了很多简单的实现。下面就是个例子
        public   class  MyAction  {
           
        public String execute() throws Exception {
                
        // do the work
                return "success";
           }

        }

        首先你会注意到的是,Struts2中的action不再继承于任何类或需要实现任何接口。实际上,它还远不只这些。按照惯例,只有"execute"方法能调用action, 但在Struts2中并非必要,任何声明为public String methodName() 方法都能通过配置来调用action.
        另外,你会注意到返回值不再是"ActionForward ",而是String, 如果你需喜欢String的形式,那在Action接口里有个帮助方法可以提供简单的结果常量,如"success", "none", "error", "input" 和 "login"。
        最后,和Struts最大的革命性的不同是, 调用action不再是带参数的。那你如何在获得你所需要的值呢?答案是"inversion of control" 或 "dependency injection", 反转控制(想了解更多可以看Martin Fowler的文章 http://www.martinfowler.com/articles/injection.html)。
        为了更好地了解反转控制,让我们来看看一个例子,如何在action处理过程中可以访问到HttpServerRequest 。在我们的例子中,我们用ServletRequestAware 接口,这个接口包含了相应属性的setter,如下
        public   interface  ServletRequestAware  {
            
        public void setServletRequest(HttpServletRequest request);
        }

        当我们继承这个接口时,我们需要通过setter为我们的HttpServerRequest 属性变量赋值:
        public   class  MyAction  implements  ServletRequestAware  {
           
        private HttpServletRequest request;
           
        public void setServletRequest(HttpServletRequest request) {
                
        this.request = request;
           }

           
        public String execute() throws Exception {
                
        // do the work using the request
                return Action.SUCCESS;
           }

        }

        看起来现在这些属性是类级别的,并不是线程安全的,但是在Struts2里并没有问题,因为每个请求过来的时候都会产生一个新的action对象实例,它并没有和其他请求共享一个对象,所以不需要考虑线程安全问题。

        现在我们还有最后一步,就是把action关联上 ServletConfigInterceptor 拦截器。这个拦截器继承了 ServletRequestAware 接口,并提供了把HttpServletRequest 注入到action中的功能。但是你现在不用担心如何配置这些,我们将在下一篇文章中具体讲述。最重要的是我们明白了拦截器和接口共同为action提供了反转控制的功能。
        这个设计的好处是能让action完全和框架解耦。action仅仅是一个被框架使用的简单的POJO。这对于单元测试但来极大的好处,你能方便的为Struts action实现 StrutsTestCase 或  MockStrutsTestCase 单元测试。

        总结
        By到现在为止,你应该已经了解了Struts2的整个请求流程,还有高层的框架概念, 你也应该能自己动手配置Struts2的action,和讲出Struts和Struts2的差别了。
        在下篇文章中,我们将会介绍一个详细的Struts应用向Struts2迁移的例子,同时我们也会介绍迁移中相关的知识,会讲述如何综合使用JSTL, JSP 和 Struts2,进一步讲述Struts和Struts2的action的差别,Struts2的配置和其他框架元素,和谈到更多的其他相关框架的特征。
        以下是对提供的参考资料的总结,按照要求结构化多个要点分条输出: 4G/5G无线网络优化与网规案例分析: NSA站点下终端掉4G问题:部分用户反馈NSA终端频繁掉4G,主要因终端主动发起SCGfail导致。分析显示,在信号较好的环境下,终端可能因节能、过热保护等原因主动释放连接。解决方案建议终端侧进行分析处理,尝试关闭节电开关等。 RSSI算法识别天馈遮挡:通过计算RSSI平均值及差值识别天馈遮挡,差值大于3dB则认定有遮挡。不同设备分组规则不同,如64T和32T。此方法可有效帮助现场人员识别因环境变化引起的网络问题。 5G 160M组网小区CA不生效:某5G站点开启100M+60M CA功能后,测试发现UE无法正常使用CA功能。问题原因在于CA频点集标识配置错误,修正后测试正常。 5G网络优化与策略: CCE映射方式优化:针对诺基亚站点覆盖农村区域,通过优化CCE资源映射方式(交织、非交织),提升RRC连接建立成功率和无线接通率。非交织方式相比交织方式有显著提升。 5G AAU两扇区组网:与三扇区组网相比,AAU两扇区组网在RSRP、SINR、下载速率和上传速率上表现不同,需根据具体场景选择适合的组网方式。 5G语音解决方案:包括沿用4G语音解决方案、EPS Fallback方案和VoNR方案。不同方案适用于不同的5G组网策略,如NSA和SA,并影响语音连续性和网络覆盖。 4G网络优化与资源利用: 4G室分设备利旧:面对4G网络投资压减与资源需求矛盾,提出利旧多维度调优策略,包括资源整合、统筹调配既有资源,以满足新增需求和提质增效。 宏站RRU设备1托N射灯:针对5G深度覆盖需求,研究使用宏站AAU结合1托N射灯方案,快速便捷地开通5G站点,提升深度覆盖能力。 基站与流程管理: 爱立信LTE基站邻区添加流程:未提供具体内容,但通常涉及邻区规划、参数配置、测试验证等步骤,以确保基站间顺畅切换和覆盖连续性。 网络规划与策略: 新高铁跨海大桥覆盖方案试点:虽未提供详细内容,但可推测涉及高铁跨海大桥区域的4G/5G网络覆盖规划,需考虑信号穿透、移动性管理、网络容量等因素。 总结: 提供的参考资料涵盖了4G/5G无线网络优化、网规案例分析、网络优化策略、资源利用、基站管理等多个方面。 通过具体案例分析,展示了无线网络优化中的常见问题及解决方案,如NSA终端掉4G、RSSI识别天馈遮挡、CA不生效等。 强调了5G网络优化与策略的重要性,包括CCE映射方式优化、5G语音解决方案、AAU扇区组网选择等。 提出了4G网络优化与资源利用的策略,如室分设备利旧、宏站RRU设备1托N射灯等。 基站与流程管理方面,提到了爱立信LTE基站邻区添加流程,但未给出具体细节。 新高铁跨海大桥覆盖方案试点展示了特殊场景下的网络规划需求。
        评论
        添加红包

        请填写红包祝福语或标题

        红包个数最小为10个

        红包金额最低5元

        当前余额3.43前往充值 >
        需支付:10.00
        成就一亿技术人!
        领取后你会自动成为博主和红包主的粉丝 规则
        hope_wisdom
        发出的红包
        实付
        使用余额支付
        点击重新获取
        扫码支付
        钱包余额 0

        抵扣说明:

        1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
        2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

        余额充值