随笔 - 63  文章 - 0  trackbacks - 0
<2009年4月>
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

常用链接

留言簿(2)

随笔分类

随笔档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜

        大家都知道,Struts控制器组件负责接受用户请求,更通模型,以及返回给用户合适的视图组件.
控制器将模型层和视图层分开,这样分离,可以为同一个模型开发出不同的视图.
        下面时Struts的三大主要组件
ActionServlet组件:充当Struts框架的中央控制器
RequestProcessor组件:充当每个子应用模块的请求处理器
Action组件:真正来处理一项具体的业务.

一. Struts的init()方法
Struts应用中只存在ActionServlet的一个实例,Servlet容器在启动时,或者用户首次请求ActionServlet时加载ActionServlet类.在这两种情况下,servlet容器都会在ActionServlet容器被加载后立即执行它的init()方法,这可以保证ActionServlet处理用户请求时已经被初始化.

下面根据Init()讲述Struts的初始化过程
  • public void init() throws ServletException {   
  •   
  •         // Wraps the entire initialization in a try/catch to better handle   
  •         // unexpected exceptions and errors to provide better feedback   
  •         // to the developer   
  •         try {   
  • //调用initInternal()方法,初始化Struts框架内的消息资源,如与系统日志相关的通知,警告,和错误消息.   
  • 1)initInternal();   
  •   
  • //调用ininOther()方法,从web.xml文件中加载ActionServlet的初始化参数,如config参数   
  • 2)initOther();   
  •   
  • //调用initServlet()方法,从web.xml文件中加载ActionServlet的URL映射信息.同时还会注册web.xml文件和Struts配置文件所使用的DTD文件,这些DTD文件用户验证web.xml和struts配置文件的语法.其中方法里的 digester类负责解析web.xml,对字符串servletMapping属性进行初始化   
  • 3) initServlet();   
  •   
  • //把ActionServlet实例放到ServletContext里   
  • getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this);   
  •   
  • //初始化一个factory,用于创建moduleConfig   
  • initModuleConfigFactory();   
  •   
  • //,加载并解析默认struts配置文件/WEB-INF/struts-config.xml,同时创建MoudleConfig实例,放到ServletContext中   
  • 4)ModuleConfig moduleConfig = initModuleConfig("", config);   
  •   
  • //加载并初始化默认子应用模块的消息资源;讲解MessageResources对象,把它存储在ServletContext中.   
  • 5)initModuleMessageResources(moduleConfig);   
  •   
  • //加载并初始化默认子应用模块的数据源,如果在struts配置文件中没有定义<data-sources >元素,忽略这一流程.   
  • 6)initModuleDataSources(moduleConfig);   
  •   
  • //加载并初始化默认子应用的所有插件   
  • 7)initModulePlugIns(moduleConfig);   
  •   
  • //冻结moduleConfig(,在方法返回之前不能修改它,否则将抛出异常)   
  • moduleConfig.freeze();   
  •            
  • //如果还有其他子应用模块,将重复4-7步   
  •       Enumeration names = getServletConfig().getInitParameterNames();   
  •             while (names.hasMoreElements()) {   
  •                 String name = (String) names.nextElement();   
  •                 if (!name.startsWith("config/")) {   
  •                     continue;   
  •                 }   
  •                 String prefix = name.substring(6);   
  •                 moduleConfig = initModuleConfig   
  •                     (prefix, getServletConfig().getInitParameter(name));   
  •                 initModuleMessageResources(moduleConfig);   
  •                 initModuleDataSources(moduleConfig);   
  •                 initModulePlugIns(moduleConfig);   
  •                 moduleConfig.freeze();   
  •      }   
  •   
  • //将各个子模块应用(除了默认的)的前缀存到一个字符数组中,并放到servletcontext中   
  • this.initModulePrefixes(this.getServletContext());   
  • //释放创建的用于读取配置文件的digester实例,释放内存   
  •             this.destroyConfigDigester();   
  •         } catch (UnavailableException ex) {   
  •             throw ex;   
  •         } catch (Throwable t) {   
  •             // The follow error message is not retrieved from internal message   
  •             // resources as they may not have been able to have been    
  •             // initialized   
  •             log.error("Unable to initialize Struts ActionServlet due to an "  
  •                 + "unexpected exception or error thrown, so marking the "  
  •                 + "servlet as unavailable.  Most likely, this is due to an "  
  •                 + "incorrect or missing library dependency.", t);   
  •             throw new UnavailableException(t.getMessage());   
  •         }       
  • }  
  •        将各个子模块应用(除了默认的)的前缀存到一个字符数组中,并放到servletcontext中,对于默认的子应用模块,在appclication范围内存放他的MoudleConfig实例的key为“org.apache.struts.action.MODULE”,其他模块如/account,存放的key为org.apache.struts.action.MODULE/account,消息,数据源和插件等部分存在servletcontext的key和上述方法类似,不在说明.


    二.ActionServlet的process方法
    ActionServlet接受到HTTP请求后,在doget()或doPost()方法中都会调用process()方法来处理请求.

  •  public void doGet(HttpServletRequest request,   
  •               HttpServletResponse response)   
  •         throws IOException, ServletException {   
  •   
  •         process(request, response);   
  •   
  • }   

  •   public void doPost(HttpServletRequest request,   

  •                HttpServletResponse response)   
  •         throws IOException, ServletException {   
  •   
  •         process(request, response);   
  •   
  • }   
  • 下面是process方法,它看上去并不复杂,但他调用的其他方法比较复杂. 
     protected void process(HttpServletRequest request, HttpServletResponse response)   

  •         throws IOException, ServletException {   
  •         //根据request里的信息从servletContext里找到相应的子模块ModuleConfig,和它下面的MessageResources,并放到request里,使其他组件可以方便的供request里取得应用配置信息和消息资源.   
  •         ModuleUtils.getInstance().selectModule(request, getServletContext());   
  • //取出MoudleConfig实例config   
  •         ModuleConfig config = getModuleConfig(request);   
  •     //根据config里这个子模块的信息,从servletcontext里,取出这个子模块的RequestProcessor实例   
  •         RequestProcessor processor = getProcessorForModule(config);   
  •     //如果processor实例为空,就新建一个.同时放到servletcontext里.   
  •         if (processor == null) {   
  •            processor = getRequestProcessor(config);   
  •         }   
  • //调用RequestProcessor的process方法处理,   
  •         processor.process(request, response);   
  •     }  

  • 三. 扩展ActionServlet
    从Struts1.1开始,为减轻ActionServlet的负担,多数功能已经移到RequestProcessor类中,所以基本不用扩展ActionServlet

    如果需要创建自己的ActionServlet,则可以创建一个它的子类.覆盖init()方法(或其他方法),可以写一些自己的操作,但要先调用super.init();
    定义如下的类:

  • package sample;    
  • public class ExtendedActionServlet extends ActionServlet {    
  •         public void init() throws ServletException {    
  •                super.init();    
  •                //do some operations    
  •                ……………    
  •         }    
  • }   


  • 扩展完类后,还应该在web.xml文件中如下配置:

  • <servlet>    
  •         <servlet-name>sample</servlet-name>    
  •         <servlet-class>sample.ExtendedActionServlet</servlet-class>    
  • </servlet>    
  •     
  • <servlet-mapping>    
  •        <servlet-name>sample</servlet-name>    
  •        <url-pattern>/action/*<url-pattern> 



  • 上面的/action/*表示负责处理所有以/action为前缀的URL,后面的/表示转义
    posted on 2009-04-05 11:10 lanxin1020 阅读(181) 评论(0)  编辑  收藏 所属分类: struts1

    只有注册用户登录后才能发表评论。


    网站导航: