现在的位置: 首页 > 综合 > 正文

Struts1.3.x中的ActionServlet源码分析之初始化

2013年02月12日 ⁄ 综合 ⁄ 共 12959字 ⁄ 字号 评论关闭
  1. ActionServlet的中的常量定义

    / /公共的日志实例

    受保护的静态日志日志= LogFactory.getLog(ActionServlet.class)在

    / /默认的配置文件的路径
    保护弦乐配置=“/ WEB-INF/struts-config.xml”的;

    / /默认的处理流程配置文件  

    保护字符串chainConfig =“ORG /阿帕奇/支柱/连锁/连锁-config.xml中”;

    / /未知   

    受保护的沼气池configDigester = NULL;

    / / convertNull若为真,则支柱中的Java包装类的初始值为空

    保护布尔convertNull = FALSE;

    / /未知    

    保护MessageResources内部=空;

    / /默认的资源文件    

    保护字符串INTERNALNAME =“org.apache.struts.action.ActionResources的”;

    / /用来验证配置文件格式的DTD文件    

    保护的String []注册= 
        { 
            “ - / / Apache软件基金会/ / DTD Struts的配置1.0 / / EN”,
            “/ org/apache/struts/resources/struts-config_1_0.dtd的”, 
            “ - / / Apache软件基金会/ / DTD Struts的配置1.1 / / EN“,
            “/ org/apache/struts/resources/struts-config_1_1.dtd的”, 
            “ - / /阿帕奇软件基金会/ / DTD Struts的配置1.2 / / EN” 
            “/ ORG /阿帕奇的/ struts/resources/struts-config_1_2.dtd“, 
            “ - / / Apache软件基金会/ / DTD Struts的配置1.3 / / EN” 
            “/ org/apache/struts/resources/struts-config_1_3.dtd”,
            “ - / / Sun Microsystems公司/ / DTD Web应用程序2.3 / / EN“ 
            “/ org/apache/struts/resources/web-app_2_3.dtd” 
        };

     / /未知   

     保护的字符串servletMapping = NULL; / /:FIXME: - 倍数?

     / /未知
     servletName保护的String = NULL;

 

2。  的ActionServlet中的init方法的执行流程

 

     公共无效的init()抛出ServletException异常{ 
        最终的String =“配置/”; 
        最终configPrefix configPrefixLength = configPrefix.length() - 1;

       
        尝试{

            / /①内部资源文件的初始化

            initInternal();

            / /②从的web.xml文件中加载的ActionServlet的初始化参数:配置\ convetrNull
            initOther();

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

            / /④ 读取的web.xml中命令月文件初始值chainConfig 
            initChain();

            / / 把servlet的对象存储到ServletContext的中,属性名为Globals.ACTION_SERVLET_KEY

            可用getservletContext()。的setAttribute(Globals.ACTION_SERVLET_KEY); / /⑤ 调用initModuleConfigFactory();和initModuleConfig(“”,
           

            initModuleConfigFactory();

            / /初始化模块需要的
            的ModuleConfig的ModuleConfig = initModuleConfig(“”,配置);

            / /⑥用户资源文件的初始化initModuleMessageResources的ModuleConfig;

            initModuleMessageResources的ModuleConfig;

            / / ⑦用户插件的初始化 initModulePlugIns的ModuleConfig; 
            initModulePlugIns的ModuleConfig;         

       / /⑧ 

          / /⑨调用的的ModuleConfig 冻结(); 固定组件配置换

             * /  
                   moduleConfig.freeze();

 

                

⑩解析以“配置/”开头的其他Struts的配置文件

/ / 遍历的web.xml中servletConfig配置的 initParameterNames

/ / 如发现以“ 配置/ “ 开始的参数,则根据此值初始化其它的的ModuleConfig

            枚举名称= getServletConfig()。getInitParameterNames();

            ,而(names.hasMoreElements()){ 
                String名称=(字符串)names.nextElement();

                如果(!name.startsWith(configPrefix)){ 
                    继续; 
                }

                字符串前缀= name.substring(configPrefixLength);

                的ModuleConfig

            / / 初始化其他模块的前缀

        

/ * 把其他模块的前缀存储到ServletContext的中,属性名为

Globals.MODULE_PREFIXES_KEY ( “ org.apache.struts.globals.MODULE_PRE 修复 “ ) * /

 

 

            this.initModulePrefixes(this.getServletContext());

          / / 设置configDigester =空,释放内存

            this.destroyConfigDigester(); 
        }的渔获(UnavailableException前){ 
            抛出前; 
        }的catch(Throwable的){ 
            / /后续的错误消息是不是从内部消息
            / /资源检索,因为他们可能已经能够
            / /初始化
            log.error(“无法初始化Struts的ActionServlet的” 
                +“意外的异常或错误抛出,所以标记
                为不可用“ +“的servlet,最有可能的,这是由于” 
                +“不正确或丢失的库依赖。 “,T); 
            扔:新UnavailableException(t.getMessage()); 
        } 
    }

 

 

  3.ActionServlet中的init()方法调用的各个方法详解

  

  ① 内部资源文件的初始化 initInternal的()方法;

    

/ / initInternal 方法中通过下面得到一个MessageResources对象

内部,= MessageResources。getMessageResourcesINTERNALNAME);

此资源文件主要包括一些消息信息的定义,具体可参考org.apache.struts.action下的ActionResources.properties文件

 

 

  ②从的web.xml文件中加载的ActionServlet的初始化参数:配置\ convetrNull initOther ();

 

    保护无效initOther()
        抛出ServletException异常{ 
        String值;

        / /得到的web.xml文件中的“配置”参数

        值= getServletConfig()。getInitParameter(“CONFIG”);

        如果(值!= NULL){ 
            配置=

       

           包装类的初始值为空,而非0

        值= getServletConfig()。getInitParameter(“convertNull”);

        (“真”。equalsIgnoreCase(价值)| |“是”。equalsIgnoreCase(价值)
            | |“打开”。equalsIgnoreCase(价值)| |“Y”。equalsIgnoreCase(价值)
            | |“1”。equalsIgnoreCase(值) ){ 
            convertNull = TRUE; 
        }

        如果(convertNull){

            //将所有的转换器注销掉,使所有值初始为null
            ConvertUtils.deregister();
            //为指定类型的数据注册转换器

            ConvertUtils.register(新BigDecimalConverter(空),
                BigDecimal.class); 
            ConvertUtils.register(新BigIntegerConverter(空)
                BigInteger.class的); 
            ConvertUtils.register(新BooleanConverter(空),Boolean.class); 
            ConvertUtils.register(新ByteConverter; 
            ConvertUtils.register(新CharacterConverter(空)Character.class的); 
            ConvertUtils.register(新DoubleConverter(空)Double.class的); 
            ConvertUtils.register(新FloatConverter(空), (空),Byte.class)Float.class); 
            ConvertUtils.register(新IntegerConverter(空),Integer.class); 
            ConvertUtils.register(新LongConverter(空)Long.class的); 
            ConvertUtils.register(新ShortConverter(空)Short.class的); 
        } 
    }

 

    ③initServlet();从web.xml文件中加载ActionServlet的初始化参数:servlet-name,加载DTD文件并把其放入HashMap缓存,读取并解析   

     web.xml中的内容

     

        抛出ServletException异常     保护无效initServlet(){ / /获取当前的Servlet的名称,即的web.xml文件中定义的的<servlet-name>         this.servletName = getServletConfig()。getServletName(); 
        

        新建沼气 ​​池沼气池沼气池=();

        / / 把当前的ActionServlet的对象放入到解析堆栈中

        digester.push(这)/ /需要考虑命名空间 ;
       

        digester.setNamespaceAware(真);

        / / 缺省值[虚假] ,解析器只是检查XML是否格式良好(形成) 
        digester.setValidating的(错误);

        为(int i = 0; <registrations.length; + = 2){ 
            URL URL = this.getClass()。的getResource(注册[1]);

            如果(的url =空){ 
                digester.register(注册[],url.toString()); 
            } 
        } 
        digester.addCallMethod(“web-app/servlet-mapping”,“addServletMapping”,2); 
        digester.addCallParam的(“web-app/servlet-mapping/servlet-name”,0); 
        digester.addCallParam(“web-app/servlet-mapping/url-pattern”,1);

        / /处理
        如果Web应用程序的部署描述符(log.isDebugEnabled的()){ 
            log.debug(web.xml的扫描控制器servlet映射“); 
        }

        InputStream中输入= 
            可用getservletContext()的getResourceAsStream(“/ WEB-INF/web.xml中”的);

        (输入== NULL){ 
            log.error(internal.getMessage(“configWebXml)); 
            抛出新的ServletException异常(internal.getMessage(的“configWebXml”)); 
        }

        { 
            digester.parse(输入); 
        }赶上(IOException异常E){ 
            log.error(internal.getMessage(“configWebXml),E),
            抛出新的ServletException异常(E); 
        }赶上(SAXException的E){ 
            log.error( internal.getMessage(“configWebXml”),E); 
            抛出新的ServletException异常(E); 
        }最后{ 
            尝试{ 
                input.close(); 
            }赶上(IOException异常E){ 
                log.error(internal.getMessage(“configWebXml) E); 
                抛出新的ServletException时(E); 
            } 
        }

        / /记录servlet上下文属性(如适用)
        的if(log.isDebugEnabled()){ 
            log.debug(“映射servlet的”+ servletName +“'='” 
                + servletMapping +“”); 
        }

        (servletMapping!= NULL){:
            可用getservletContext()。的setAttribute(Globals.SERVLET_KEY,servletMapping); 
        } 
    }

    

     

      ④ 读取的web.xml中命令月文件初始值chainConfig  initChain();

         

         保护无效initChain()
        { 
        / /解析配置文件中指定的路径或资源
        的try { 
            String值抛出ServletException异常;

            //读取web.xml文件中的chainConfig参数值,如没有chainConfig参数,则使用默认"org/apache/struts/chain/chain-config.xml"

            值= getServletConfig()。的getInitParameter(“chainConfig”);

            如果(值!= NULL){ 
                chainConfig =值; 
            }

            ConfigParser分析器=新ConfigParser(); 
            列表网址= splitAndResolvePaths(chainConfig); 
            URL资源;

            (迭代器I = urls.iterator(); i.hasNext();) 
                资源=(URL)i.next(); 
                log.info(“中链目录”+资源);

                / / 
        赶上(例外五){             log.error(“异常加载资源”,E);             抛出新的ServletException时(E);         }    }

 

   

    ⑤ 调用 initModuleConfigFactory();和 initModuleConfig(“”,配置); 创建的ModuleConfig 对象的Struts中的MessageResource

     插件,数据源等,都是通过的ModuleConfig来实现的

    

        保护无效initModuleConfigFactory(){ / / 得到的web.xml中“configFactory”参数,如果找不到,则使用默认工厂
       

        字符串configFactory = 
            getServletConfig()。getInitParameter(“configFactory);

        (configFactory!= NULL){ 
            ModuleConfigFactory.setFactoryClass(configFactory); 
        } 
        }

 

        受保护的的的ModuleConfig initModuleConfig(前缀字符串,字符串路径)
        抛出ServletException异常
        的if(log.isDebugEnabled()){ 
            log.debug(“初始化模块路径'”+前缀
                +“'配置'”+路径+“”); 
        }

        / /解析配置此的模块
        ModuleConfigFactory factoryObject()= ModuleConfigFactory.createFactory; 
        的ModuleConfig配置= factoryObject.createModuleConfig(前缀);

        / /配置沼气池实例,我们将使用
        沼气池沼气池= initConfigDigester();

        * /

        列表的URL = splitAndResolvePaths 
        URL URL (路径);

        (迭代器I = urls.iterator(); i.hasNext();}} { 
            URL =(URL)i.next(); 
            digester.push(配置); 
            this.parseModuleConfigFile(沼气池,URL); 
        }

        / / 把配置存储到ServletContext的中 属性名为Globals.MODULE_KEY

        可用getservletContext()。的setAttribute(Globals.MODULE_KEY 
            + config.getPrefix(),配置);

        配置返回; 
    }

       

    ⑥用户资源文件的初始化initModuleMessageResources的ModuleConfig;

   

       保护无效的ModuleConfig配置initModuleMessageResources 
        抛出ServletException异常{

        / / 从的ModuleConfig中读取所有的资源文件

        保护无效的ModuleConfig配置initModuleMessageResources 
        抛出ServletException异常{ 
        MessageResourcesConfig [] MRCS = config.findMessageResourcesConfigs();

        为(int i = 0; <mrcs.length; + +){ 
            如果((MRCS [I]。getFactory()== NULL)
                | |(MRCS [I]的getParameter()== NULL)){ 
                继续; 
            }

            的if(log.isDebugEnabled()){ 
                log.debug(“初始化模块路径'”+ config.getPrefix()
                    +“'信息资源'”+ MRCS [I]的getParameter()
                    +“'”); 
            }

            弦乐厂= MRCS [I]。getFactory();

            MessageResourcesFactory.setFactoryClass(工厂);

            MessageResourcesFactory factoryObject = 
                MessageResourcesFactory.createFactory();

            factoryObject.setConfig(MRCS []);

            MessageResources资源= 
                factoryObject.createResources(MRCS [I]的getParameter());

                config.getPrefix(),资源);         }     }         MessageResourcesConfig [] MRCS = config.findMessageResourcesConfigs();

        为(int i = 0; <mrcs.length; + +){ 
            如果((MRCS [I]。getFactory()== NULL)
                | |(MRCS [I]的getParameter()== NULL)){ 
                继续; 
            }

            的if(log.isDebugEnabled()){ 
                log.debug(“初始化模块路径'”+ config.getPrefix()
                    +“'信息资源'”+ MRCS [I]的getParameter()
                    +“'”); 
            }

            弦乐厂= MRCS [I]。getFactory();

            MessageResourcesFactory.setFactoryClass(工厂);

            MessageResourcesFactory factoryObject = 
                MessageResourcesFactory.createFactory();

            factoryObject.setConfig(MRCS []);

            MessageResources资源= 
                factoryObject.createResources(MRCS [I]的getParameter());

                config.getPrefix(),资源);         }     }

 

    ⑦用户插件的初始化 initModulePlugIns的ModuleConfig; 

 

       的保护无效initModulePlugIns(配置的ModuleConfig)
        抛出ServletException异常{ 
        (log.isDebugEnabled()){ 
            log.debug(“初始化模块路径'的”+ config.getPrefix()
                +“”插件“); 
        }

        / / 从的ModuleConfig中读取所有的插件文件

        PlugInConfig [] plugInConfigs = config.findPlugInConfigs(); 
        插件[]插件=新的插件[plugInConfigs.length];

        / / 把所有插件存储到ServletContext的中

        可用getservletContext()的setAttribute(Globals.PLUG_INS_KEY 
            + config.getPrefix(),插件);

        (INT I = 0; <plugIns.length; + +){ 
            尝试{ 
                插件[I] = 
                    ( ​​插件)RequestUtils.applicationInstance(plugInConfigs [I] 
                        。getClassName()); 
                BeanUtils.populate(插件[I],plugInConfigs [一]。getProperties());

                / /通过当前的插件配置对象插件
                / /声明
                / /这个插件的配置对象所需要的瓷砖
                尝试{ 
                    PropertyUtils.setProperty(插件[I],
                        “currentPlugInConfigObject” 如果插件,该属性设置plugInConfigs []); 
                }赶上(例外五){ 
                    ;

                    / / FIXME每当我们静静的失败,我们必须记录一个有效的
                    / /这样做的理由。为什么我们应该静静的失败,如果
                    不能设置一个/ /属性插件?

                    / ** 
                     *版本1.138-1.140之间塞德里克这些变化。
                     *已捕获的异常处理容器
                     实施严格的安全。这是错误
                     *#15736 
                     * 
                     *推荐我们使currentPlugInConfigObject的的
                     插件接口的部分*如果我们可以,罗布
                     * / 
                }

                插件[I]。的init(配置); 
            }渔获(留言内容E){ 
                扔é; 
            }赶上(例外五){ 
                弦乐ERRMSG = 
                    internal.getMessage(的“plugIn.init”,
                        plugInConfigs [I]。getClassName() );

                日志(ERRMSG,E); 
                扔新UnavailableException(ERRMSG); 
            } 
        } 
    }

 

至此,的ActionServlet的初始化工作完成! 

抱歉!评论已关闭.