欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

struts2 18拦截器详解(十六)

程序员文章站 2022-10-31 18:23:13
actionmappingparametersinteceptor      actionmappingparametersinteceptor拦截器处于default...
actionmappingparametersinteceptor

 

   actionmappingparametersinteceptor拦截器处于defaultstack第十四的位置,该拦截器继承自parametersinterceptor,也是用于把参数设置到valuestack中,只不过该拦截器的参数是来源于actionmapping中,而不是来自请求参数。往valuestack中设置值的逻辑与parametersinterceptor一模一样,正是这个原因才把parametersinterceptor拦截器放在了该拦截器之前讲解。大家可以发现该拦截器只是覆盖了parametersinterceptor的两个方法:

[java] view plaincopy

@override  

protected map<string, object> retrieveparameters(actioncontext ac) {  

    //获取acitonmapping对象  

    actionmapping mapping = (actionmapping) ac.get(servletactioncontext.action_mapping);  

    if (mapping != null) {  

        return mapping.getparams();//获取acitonmapping参数  

    } else {  

        return collections.emptymap();  

    }  

}  

  

@override//将参数设置到actioncontext的parameters map中  

protected void addparameterstocontext(actioncontext ac, map newparams) {  

    //获取请求参数  

    map previousparams = ac.getparameters();  

    map combinedparams = null;  

    if (previousparams != null) {  

        combinedparams = new treemap(previousparams);  

    } else {  

        combinedparams = new treemap();  

    }  

    //newparams为actionmapping中的经过了合法性检查后的合法参数  

    combinedparams.putall(newparams);  

    //将请求参数与合法参数一起设置到actioncontext的parameters map中  

    ac.setparameters(combinedparams);  

}  

 

   因为现在执行的是actionmappingparametersinteceptor拦截器所以在parametersinterceptor的dointercept方法中调用的retrieveparameters方法是actionmappingparametersinteceptor拦截器中的retrieveparameters,这是java多态的表现,所以该拦截器通过覆盖父类的retrieveparameters方法达到了改变参数来源的目的。

   在parametersinterceptor拦截器的setparameters方法中最后一句调用了addparameterstocontext方法,而在actionmappingparametersinteceptor子类中覆盖了addparameterstocontext方法,所以执行的也是actionmappingparametersinteceptor拦截器定义的addparameterstocontext方法,将将请求参数与合法参数一起设置到actioncontext的parameters map中。

 

   但有一点需要大家注意,就是actionmapping的参数永远为null,所以执行该拦截器时为valuestack设置值的操作根本就不会发生,下面通过源代码进行证明。在证明之前actionconfig,actionmapping,actionmapper之间的关系需要明白,actionconfig对象保存的是action的配置信息,actionmapping对象保存的是action的映射信息,actionmapper是根据你访问的url去actionconfig中进行匹配再映射成actionmapping对象。例如,一个action的配置中可以有多个方法,可以有多个result,但是在执行的时候只能执行action中的一个方法,返回的时候只能有一个result而actionmapper的功能就是根据url与acitonconfig映射成actionmapping对象。

 

strutsprepareandexecutefilter的dofilter方法:

 

[java]  

public void dofilter(servletrequest req, servletresponse res, filterchain chain) throws ioexception, servletexception {  

    //省略...  

    actionmapping mapping = prepare.findactionmapping(request, response, true);//调用prepare对象的findactionmapping  

    //省略...  

}  

 

下面是findactionmapping方法:

[java]  

public actionmapping findactionmapping(httpservletrequest request, httpservletresponse response, boolean forcelookup) {  

    actionmapping mapping = (actionmapping) request.getattribute(struts_action_mapping_key);  

    if (mapping == null || forcelookup) {  

        try {  

            //去容器中找actionmapper对象,并调用actionmapper对象的getmapping方法返回actionmapping对象  

            mapping = dispatcher.getcontainer().getinstance(actionmapper.class).getmapping(request, dispatcher.getconfigurationmanager());  

            if (mapping != null) {  

                request.setattribute(struts_action_mapping_key, mapping);  

            }  

        } catch (exception ex) {  

            dispatcher.senderror(request, response, servletcontext, httpservletresponse.sc_internal_server_error, ex);  

        }  

    }  

    return mapping;  

}  

 

   actionmapper是一个接口,在struts2中其默认实现类是org.apache.struts2.dispatcher.mapper.defaultactionmapper,下面是该类的getmapping方法:

[java]  

public actionmapping getmapping(httpservletrequest request, configurationmanager configmanager) {  

    actionmapping mapping = new actionmapping();//新建一个actionmapping对象  

    string uri = geturi(request);//获取uri  

  

    int indexofsemicolon = uri.indexof(";");  

    uri = (indexofsemicolon > -1) ? uri.substring(0, indexofsemicolon) : uri;//处理 uri  

  

    uri = dropextension(uri, mapping);//去掉uri后缀  

    if (uri == null) {  

        return null;  

    }  

    //解析action的namespace与name  

    parsenameandnamespace(uri, mapping, configmanager);  

    //处理特殊参数  

    handlespecialparameters(request, mapping);  

  

    if (mapping.getname() == null) {  

        return null;  

    }  

    //解析actionname,因为struts2可以支持动态方法调用,如:xxxaction!login  

    parseactionname(mapping);  

  

    return mapping;  

}  

 

   一开始以为会在handlespecialparameters设置actionmapping参数,但进去看了以后发现也没有为actionmapping设置参数的操作,所以对于用defaultactionmapper作为actionmapper的的实现类的话,actionmapping中的参数是为null的。

 

   到此该拦截器就讲到这里了,准备下一个拦截器......