struts1源码学习7,action处理核心ComposableRequestProcessor

来源:互联网 发布:web网络考勤管理系统 编辑:程序博客网 时间:2024/06/05 02:13

先做个铺垫,先回忆一下ActionServlet.initChain的细节

 public void addRuleInstances(Digester digester) {        // Add rules for a catalog element        digester.addRule("*/" + getCatalogElement(),                         new ConfigCatalogRule(nameAttribute, catalogClass));        digester.addSetProperties("*/" + getCatalogElement());        // Add rules for a chain element        digester.addObjectCreate("*/" + getChainElement(),                                 getChainClass(),                                 getClassAttribute());        digester.addSetProperties("*/" + getChainElement());        digester.addRule("*/" + getChainElement(),                         new ConfigRegisterRule(nameAttribute));        // Add rules for a command element        digester.addObjectCreate("*/" + getCommandElement(),                                 null,                                 getClassAttribute());        digester.addSetProperties("*/" + getCommandElement());        digester.addRule("*/" + getCommandElement(),                         new ConfigRegisterRule(nameAttribute));        // Add rules for a define element<span style="white-space:pre"></span>//getNameAttribute()实际的值是"name",后面那个参数是"className"        digester.addRule("*/" + getDefineElement(),                         new ConfigDefineRule(getNameAttribute(),                                              getClassAttribute()));    }
这里面有个特别的地方,在于define标签的处理。看ConfigDefineRule.begin代码

public void begin(String namespace, String name, Attributes attributes)        throws Exception {        // Extract the actual name and implementation class to use<span style="white-space:pre"></span>//获取name属性值        String nameValue = attributes.getValue(nameAttribute);<span style="white-space:pre"></span>//获取className属性值chain-config.xml        String classValue = attributes.getValue(classAttribute);        //默认情况下org/apache/struts/chain/chain-config.xml<define name="lookup" className="org.apache.commons.chain.generic.LookupCommand"/>         digester.addObjectCreate("*/" + nameValue, classValue);        digester.addSetProperties("*/" + nameValue);        digester.addRule("*/" + nameValue,                         new ConfigRegisterRule(nameAttribute));    }
org.apache.commons.chain.generic.LookupCommand
LookupCommand)


1、init方法

  public void init(ActionServlet servlet, ModuleConfig moduleConfig)        throws ServletException {        LOG.info(            "Initializing composable request processor for module prefix '"            + moduleConfig.getPrefix() + "'");        //清空actions,然后赋值servlet和moduleConfig        super.init(servlet, moduleConfig);        //赋值,this.catalogFactory = CatalogFactory.getInstance();        initCatalogFactory(servlet, moduleConfig);        //拿到ControllerConfig配置        ControllerConfig controllerConfig = moduleConfig.getControllerConfig();        //这个默认值是struts        String catalogName = controllerConfig.getCatalog();        /* CatalogFactory.getInstance().getCatalog         * 这个在catalogFactory实际上是在ActionServlet.init中的initChain来赋值初始化的         * 在ActionServlet.initChain中,解析xml时,会根据catalog标签生成一个org.apache.commons.chain.impl.CatalogBase。         * 而catalogFactory中有两个属性一个是catalog,另一个是catalogs(Map),这两个属性专门存放这些         * CatalogBase对象,其中没有name的会放在catalog,有name的则以键值对的形式放入catalogs中         */        catalog = this.catalogFactory.getCatalog(catalogName);        if (catalog == null) {            throw new ServletException("Cannot find catalog '" + catalogName                + "'");        }        //默认值是servlet-standard        String commandName = controllerConfig.getCommand();        /*         * 找到名字是servlet-standard的command         * 回忆一下,在Action.initChain中,碰到chain标签时会这样解析。         * 1、 digester.addObjectCreate生成org.apache.commons.chain.impl.ChainBase对象         * 2、 digester.addSetProperties给对象属性赋值         * 3、 digester.addRule(/chain",new ConfigRegisterRule(nameAttribute));         * 其中rule,是这样处理的。拿到刚刚生成的ChainBase,和在digester栈中ChainBase的前一个对象(称之为next对象),         * 接着调用next.addCommand方法,ChainBase作为参数         * 这个next必须实现Command接口         * 但是,如果这个next是Catalog,那么调用的是addCommand(name,chainBase),         * 如果next是ChainBase对象,那么调用addCommand(chainBase)         * 差别就在于有没name         *          */        command = catalog.getCommand(commandName);        if (command == null) {            throw new ServletException("Cannot find command '" + commandName                + "'");        }        //默认情况下,这个值是空的        this.setActionContextClassName(controllerConfig.getProperty(                ACTION_CONTEXT_CLASS));    }
2、process方法

    public void process(HttpServletRequest request, HttpServletResponse response)        throws IOException, ServletException {        // Wrap the request in the case of a multipart request    //处理"multipart/form-data",即上传文件的表单时,将request包装成MultipartRequestWrapper        request = processMultipart(request);        /*这里建立一个ActionContext,如果用户没指定actionContextClass的话,         * 默认new ServletActionContext(servletContext, request, response)         * 这个ActionContext包含了request,response,servletContext和ModuleConfig         */        // Create and populate a Context for this request        ActionContext context = contextInstance(request, response);        // Create and execute the command.        try {            if (LOG.isDebugEnabled()) {                LOG.debug("Using processing chain for this request");            }            //执行ChainCommand,实际上这个command就是chainBase            command.execute(context);        } catch (Exception e) {            // Execute the exception processing chain??            throw new ServletException(e);        }        // Release the context.        context.release();    }


0 0
原创粉丝点击