`
bolan392
  • 浏览: 277038 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

阅读更多
  1. ActionServlet中的常量定义

    //公共的日志实例

    protected static Log log = LogFactory.getLog(ActionServlet.class);

    //默认的配置文件路径
    protected String config = "/WEB-INF/struts-config.xml";

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

    protected String chainConfig = "org/apache/struts/chain/chain-config.xml";

    //未知   

    protected Digester configDigester = null;

    //convertNull若为true,则struts中Java包装类的初始值为null

    protected boolean convertNull = false;

    //未知    

    protected MessageResources internal = null;

    //默认的资源文件    

    protected String internalName = "org.apache.struts.action.ActionResources";

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

    protected String[] registrations =
        {
            "-//Apache Software Foundation//DTD Struts Configuration 1.0//EN",
            "/org/apache/struts/resources/struts-config_1_0.dtd",
            "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN",
            "/org/apache/struts/resources/struts-config_1_1.dtd",
            "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN",
            "/org/apache/struts/resources/struts-config_1_2.dtd",
            "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN",
            "/org/apache/struts/resources/struts-config_1_3.dtd",
            "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN",
            "/org/apache/struts/resources/web-app_2_3.dtd"
        };

     //未知   

     protected String servletMapping = null; // :FIXME: - multiples?

     //未知
     protected String servletName = null;

 

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

 

     public void init() throws ServletException {
        final String configPrefix = "config/";
        final int configPrefixLength = configPrefix.length() - 1;

       
        try {

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

            initInternal();

            //②从web.xml文件中加载ActionServlet的初始化参数:config\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, this);
            //⑤调用 initModuleConfigFactory(); 和 initModuleConfig("", config); 创建ModuleConfig 对象。Struts中的MessageResource、PlugIn、数据源等,都是通过ModuleConfig来实现的

            initModuleConfigFactory();

            // Initialize modules as needed
            ModuleConfig moduleConfig = initModuleConfig("", config);

            //⑥用户资源文件的初始化 initModuleMessageResources(moduleConfig);

            initModuleMessageResources(moduleConfig);

            //⑦用户插件的初始化 initModulePlugIns(moduleConfig); 
            initModulePlugIns(moduleConfig);         

       //⑧ 把struts配置文件中的其他配置存储到servletContext中,包括 
            initModuleFormBeans(moduleConfig);
            initModuleForwards(moduleConfig);
            initModuleExceptionConfigs(moduleConfig);
            initModuleActions(moduleConfig);           

          //⑨ 调用moduleConfig.freeze();

             /* 使ModuleConfig中的 actionConfigs/actionConfigList exceptions formBeansforwardsmessageResourcesplugIns等的配置等变得不可改变 */ 
                   moduleConfig.freeze();

 

                

⑩ 解析以"config/"开头的其他struts配置文件

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

// 如发现以" config/ " 开始的parameter,则根据此值初始化其它的ModuleConfig

            Enumeration names = getServletConfig().getInitParameterNames();

            while (names.hasMoreElements()) {
                String name = (String) names.nextElement();

                if (!name.startsWith(configPrefix)) {
                    continue;
                }

                String prefix = name.substring(configPrefixLength);

                moduleConfig =
                    initModuleConfig(prefix,
                        getServletConfig().getInitParameter(name));
                initModuleMessageResources(moduleConfig);
                initModulePlugIns(moduleConfig);
                initModuleFormBeans(moduleConfig);
                initModuleForwards(moduleConfig);
                initModuleExceptionConfigs(moduleConfig);
                initModuleActions(moduleConfig);
                moduleConfig.freeze();
            }

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

        

/* 把其他模块prefixes存储到servletContext中,属性名为

Globals.MODULE_PREFIXES_KEY " org.apache.struts.globals.MODULE_PREFIXES " */

 

 

            this.initModulePrefixes(this.getServletContext());

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

            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());
        }
    }

 

 

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

  

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

    

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

internal = MessageResources.getMessageResources(internalName);

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

 

 

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

 

    protected void initOther()
        throws ServletException {
        String value;

        //得到web.xml文件中的"config"参数

        value = getServletConfig().getInitParameter("config");

        if (value != null) {
            config = value;
        }

        //获得web.xml文件中convertNull的值,如果此参数的值为true,则所有数值型类型(Integer,Double)的Java

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

        value = getServletConfig().getInitParameter("convertNull");

        if ("true".equalsIgnoreCase(value) || "yes".equalsIgnoreCase(value)
            || "on".equalsIgnoreCase(value) || "y".equalsIgnoreCase(value)
            || "1".equalsIgnoreCase(value)) {
            convertNull = true;
        }

        if (convertNull) {

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

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

 

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

     web.xml的内容

     

     protected void initServlet()
        throws ServletException {
        //获取当前Servlet的名称,即web.xml文件中定义的<servlet-name>
        this.servletName = getServletConfig().getServletName();

        Digester digester = new Digester();

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

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

        digester.setNamespaceAware(true);

        // 缺省值[false] ,解析器只是检查XML是否格式良好(well formed) 
        digester.setValidating(false);

        for (int i = 0; i < registrations.length; i += 2) {
            URL url = this.getClass().getResource(registrations[i + 1]);

            if (url != null) {
                digester.register(registrations[i], 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);

        // Process the web application deployment descriptor
        if (log.isDebugEnabled()) {
            log.debug("Scanning web.xml for controller servlet mapping");
        }

        InputStream input =
            getServletContext().getResourceAsStream("/WEB-INF/web.xml");

        if (input == null) {
            log.error(internal.getMessage("configWebXml"));
            throw new ServletException(internal.getMessage("configWebXml"));
        }

        try {
            digester.parse(input);
        } catch (IOException e) {
            log.error(internal.getMessage("configWebXml"), e);
            throw new ServletException(e);
        } catch (SAXException e) {
            log.error(internal.getMessage("configWebXml"), e);
            throw new ServletException(e);
        } finally {
            try {
                input.close();
            } catch (IOException e) {
                log.error(internal.getMessage("configWebXml"), e);
                throw new ServletException(e);
            }
        }

        // Record a servlet context attribute (if appropriate)
        if (log.isDebugEnabled()) {
            log.debug("Mapping for servlet '" + servletName + "' = '"
                + servletMapping + "'");
        }

        if (servletMapping != null) {
            getServletContext().setAttribute(Globals.SERVLET_KEY, servletMapping);
        }
    }

    

     

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

         

         protected void initChain()
        throws ServletException {
        // Parse the configuration file specified by path or resource
        try {
            String value;

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

            value = getServletConfig().getInitParameter("chainConfig");

            if (value != null) {
                chainConfig = value;
            }

            ConfigParser parser = new ConfigParser();
            List urls = splitAndResolvePaths(chainConfig);
            URL resource;

            for (Iterator i = urls.iterator(); i.hasNext();) {
                resource = (URL) i.next();
                log.info("Loading chain catalog from " + resource);

                // chainConfig 替换了原来传统的在 RequestProcessor 类中执行的 HTTP 请求处理
                parser.parse(resource);
            }
        } catch (Exception e) {
            log.error("Exception loading resources", e);
            throw new ServletException(e);
        }
    }

 

   

    ⑤调用 initModuleConfigFactory(); 和 initModuleConfig("", config); 创建ModuleConfig 对象。Struts中的MessageResource、

     PlugIn、数据源等,都是通过ModuleConfig来实现的

    

        protected void initModuleConfigFactory() {
        // 得到web.xml中"configFactory"参数,如果找不到,则使用 默认工厂

        String configFactory =
            getServletConfig().getInitParameter("configFactory");

        if (configFactory != null) {
            ModuleConfigFactory.setFactoryClass(configFactory);
        }
        }

 

        protected ModuleConfig initModuleConfig(String prefix, String paths)
        throws ServletException {
        if (log.isDebugEnabled()) {
            log.debug("Initializing module path '" + prefix
                + "' configuration from '" + paths + "'");
        }

        // Parse the configuration for this module
        ModuleConfigFactory factoryObject = ModuleConfigFactory.createFactory();
        ModuleConfig config = factoryObject.createModuleConfig(prefix);

        // Configure the Digester instance we will use
        Digester digester = initConfigDigester();

        /* 循环struts配置文件(用","分开的多个struts配置文件)并解析, parseModuleConfigFile 执行之后可以 从struts-config.xml等配置文件中得到 actionConfigs/actionConfigList exceptions formBeansforwardsmessageResourcesplugIns等的配置,并把得到的所有值封装到对象ModuleConfig对象(config)中 */

        List urls = splitAndResolvePaths(paths);
        URL url;

        for (Iterator i = urls.iterator(); i.hasNext();) {
            url = (URL) i.next();
            digester.push(config);
            this.parseModuleConfigFile(digester, url);
        }

        // 把config存储到servletContext中 属性名为Globals.MODULE_KEY

        getServletContext().setAttribute(Globals.MODULE_KEY
            + config.getPrefix(), config);

        return config;
    }

       

    ⑥用户资源文件的初始化 initModuleMessageResources(moduleConfig);

   

       protected void initModuleMessageResources(ModuleConfig config)
        throws ServletException {

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

        protected void initModuleMessageResources(ModuleConfig config)
        throws ServletException {
        MessageResourcesConfig[] mrcs = config.findMessageResourcesConfigs();

        for (int i = 0; i < mrcs.length; i++) {
            if ((mrcs[i].getFactory() == null)
                || (mrcs[i].getParameter() == null)) {
                continue;
            }

            if (log.isDebugEnabled()) {
                log.debug("Initializing module path '" + config.getPrefix()
                    + "' message resources from '" + mrcs[i].getParameter()
                    + "'");
            }

            String factory = mrcs[i].getFactory();

            MessageResourcesFactory.setFactoryClass(factory);

            MessageResourcesFactory factoryObject =
                MessageResourcesFactory.createFactory();

            factoryObject.setConfig(mrcs[i]);

            MessageResources resources =
                factoryObject.createResources(mrcs[i].getParameter());

            resources.setReturnNull(mrcs[i].getNull());
            resources.setEscape(mrcs[i].isEscape());
            getServletContext().setAttribute(mrcs[i].getKey()
                + config.getPrefix(), resources);
        }
    }
        MessageResourcesConfig[] mrcs = config.findMessageResourcesConfigs();

        for (int i = 0; i < mrcs.length; i++) {
            if ((mrcs[i].getFactory() == null)
                || (mrcs[i].getParameter() == null)) {
                continue;
            }

            if (log.isDebugEnabled()) {
                log.debug("Initializing module path '" + config.getPrefix()
                    + "' message resources from '" + mrcs[i].getParameter()
                    + "'");
            }

            String factory = mrcs[i].getFactory();

            MessageResourcesFactory.setFactoryClass(factory);

            MessageResourcesFactory factoryObject =
                MessageResourcesFactory.createFactory();

            factoryObject.setConfig(mrcs[i]);

            MessageResources resources =
                factoryObject.createResources(mrcs[i].getParameter());

            resources.setReturnNull(mrcs[i].getNull());
            resources.setEscape(mrcs[i].isEscape());
            getServletContext().setAttribute(mrcs[i].getKey()
                + config.getPrefix(), resources);
        }
    }

 

    ⑦用户插件的初始化 initModulePlugIns(moduleConfig); 

 

       protected void initModulePlugIns(ModuleConfig config)
        throws ServletException {
        if (log.isDebugEnabled()) {
            log.debug("Initializing module path '" + config.getPrefix()
                + "' plug ins");
        }

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

        PlugInConfig[] plugInConfigs = config.findPlugInConfigs();
        PlugIn[] plugIns = new PlugIn[plugInConfigs.length];

        // 把所有plugIns存储到servletContext中

        getServletContext().setAttribute(Globals.PLUG_INS_KEY
            + config.getPrefix(), plugIns);

        for (int i = 0; i < plugIns.length; i++) {
            try {
                plugIns[i] =
                    (PlugIn) RequestUtils.applicationInstance(plugInConfigs[i]
                        .getClassName());
                BeanUtils.populate(plugIns[i], plugInConfigs[i].getProperties());

                // Pass the current plugIn config object to the PlugIn.
                // The property is set only if the plugin declares it.
                // This plugin config object is needed by Tiles
                try {
                    PropertyUtils.setProperty(plugIns[i],
                        "currentPlugInConfigObject", plugInConfigs[i]);
                } catch (Exception e) {
                    ;

                    // FIXME Whenever we fail silently, we must document a valid
                    // reason for doing so.  Why should we fail silently if a
                    // property can't be set on the plugin?

                    /**
                     * Between version 1.138-1.140 cedric made these changes.
                     * The exceptions are caught to deal with containers
                     * applying strict security. This was in response to bug
                     * #15736
                     *
                     * Recommend that we make the currentPlugInConfigObject part
                     * of the PlugIn Interface if we can, Rob
                     */
                }

                plugIns[i].init(this, config);
            } catch (ServletException e) {
                throw e;
            } catch (Exception e) {
                String errMsg =
                    internal.getMessage("plugIn.init",
                        plugInConfigs[i].getClassName());

                log(errMsg, e);
                throw new UnavailableException(errMsg);
            }
        }
    }

 

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    struts1.3.jar

    10. **预定义的ActionServlet配置**:在web.xml中,可以预定义ActionServlet的配置,包括初始化参数、过滤器设置等,使得部署更加灵活。 11. **Tiles框架集成**:Struts 1.3可以与Tiles框架结合使用,实现页面布局...

    struts1.3.15.1高危漏洞修复版ssh包

    在Struts 1.x版本中,存在一个名为CVE-2017-9791的安全漏洞,这是一个高危级别的远程代码执行漏洞,攻击者可以利用这个漏洞执行任意系统命令,对服务器安全构成严重威胁。SSH(Spring、Struts、Hibernate)是一种...

    对struts1.x与struts2.x的区别的总结

    - **Struts1.x** 主要基于Front Controller模式,所有的请求都通过一个单一的Servlet(ActionServlet)进行处理。 - **Struts2.x** 基于拦截器(Interceptor)模式,提供更灵活的控制流,可以组合多个拦截器来实现...

    struts1.3.rar

    5. **Commons Digester** (`commons-digester-1.8.jar`): 这个库用于解析XML配置文件,自动创建和初始化Java对象。在Struts中,它用于读取struts-config.xml配置文件,创建Action和Form Bean实例。 6. **Commons ...

    struts1.x和struts2.x区别

    在Struts1.x中,Action是核心组件之一,它必须继承自org.apache.struts.action.Action类,并且需要覆盖execute方法。Action对象由框架创建和管理,每一个HTTP请求都对应一个Action实例。然而,在Struts2.x中,Action...

    Struts1.x常用的开发包,需要学习struts1.x朋友可以下载

    11. **生命周期管理**:Struts1.x对ActionForm对象的生命周期进行了管理,包括初始化、清理、创建和销毁等步骤,确保了内存的合理使用。 学习Struts1.x需要理解其设计理念,掌握配置文件的编写,熟练运用Action、...

    struts1.x技术课程讲解.pdf

    2. **ActionServlet**:Struts1.x 的核心组件,负责初始化框架、接收 HTTP 请求并将请求分发给相应的 Action 类处理。 3. **ActionMapping**:配置文件 struts-config.xml 中定义的一个节点,用于描述一个 Action ...

    saaj-api-1.3.jar

    saaj-api-1.3.jar saaj-api-1.3.jar

    struts1.x 和 struts2.x向Action里填充jsp参数原理

    本篇文章将深入探讨Struts1.x和Struts2.x在向Action中填充JSP参数的原理。 Struts1.x的工作原理: Struts1的核心是ActionServlet,它是一个实现了Servlet接口的控制器。当用户发起HTTP请求时,请求会被Dispatcher...

    Struts1.x系列教程(网摘-全)

    在Struts1.x中,Model代表业务逻辑,View负责数据展示,Controller处理用户请求并协调Model和View。 2. **Action类**:每个HTTP请求都对应一个Action类,这是Struts1.x的核心组件。Action类处理用户请求,执行相应...

    Struts1.x_action

    在Struts1.x中,Action类是核心组件之一,它负责处理HTTP请求,并将这些请求映射到相应的业务逻辑。Action类通常继承自`org.apache.struts.action.Action`基类,并覆盖其execute方法。执行execute方法时,Action会...

    Struts1.x_Project.zip

    1. **ActionServlet**:Struts的入口点,负责初始化配置信息和拦截HTTP请求。 2. **ActionForm**:封装用户请求的数据,与视图层进行数据交换。 3. **Action**:处理业务逻辑,每个Action对应一个用户请求,负责调用...

    Struts1.x的登录示例

    在Struts1.x中,ActionServlet作为控制器,ActionForm对象作为模型和控制器之间的数据载体,而JSP页面作为视图。 2. **配置文件**: - **struts-config.xml**:这是Struts1.x的核心配置文件,定义了ActionMapping...

    struts1.x入门教程

    - **web.xml**:这是Servlet容器的配置文件,我们在这里配置ActionServlet,设置其初始化参数,指定struts-config.xml的路径,并将默认欢迎文件设置为login.jsp。 - **struts-config.xml**:这是Struts框架的核心...

    struts1.3用户指南

    2. **Action类**:在Struts1.3中,Action类是处理用户请求的核心,它实现了Action接口,负责接收请求、处理业务逻辑,并通过ActionForward来决定下一步的跳转。 3. **配置文件**:Struts1.3的配置主要在struts-...

    xdoclet1 xdoclet1 spring3.0.5、struts1.3、struts2.1、 servlet

    其中包括xdoclet2与hibernate3.6的整合xdoclet1.2.3分别与spring3.0.5、struts1.3、struts2.1、 servlet的整合配置。其中还有相应的.xdt文件模板,其中struts2.1.xdt为自己写的。 需要xdoclet1.2.3 ...

    struts1.x apps 所有最新的Struts1.x项目应用

    1. **ActionServlet**:这是Struts框架的核心,作为Servlet拦截请求,根据配置文件(struts-config.xml)将请求分发到相应的Action。 2. **Action**:开发者自定义的类,负责处理用户请求,通常会与业务逻辑层交互...

    java Struts 1.x 框架 Web 开发

    2. **Action类**:在Struts 1.x中,Action 类是处理用户请求的核心组件。每个Action对应一个特定的用户动作,它接收HTTP请求,执行相应的业务逻辑,并通过ActionForward指定视图(JSP页面)进行响应。 3. **配置...

    struts1.3源码.rar

    在源码中,我们可以看到这些核心组件的实现细节,例如ActionServlet如何调度请求,ActionForm如何验证数据,Action类如何处理业务逻辑,以及配置文件的解析逻辑等。深入阅读源码有助于我们理解框架的内部工作流程,...

    struts 1.3 API.zip

    - `ActionServlet`:Struts的Servlet实现,负责初始化Struts配置和拦截器链。 - `ActionSupport`:Action的基础类,包含了一些常用的方法和属性,如国际化支持、错误/警告处理等。 - `TilesPlugin`:用于集成...

Global site tag (gtag.js) - Google Analytics