webwork拦截器使用心得

1. Interceptor(拦截器)框架
    Interceptor(拦截器)将Action共用的行为独立出来,在Action执行前后运行。这也就是我们所说的AOP(Aspect Oriented Programming,面向切面编程),它是分散关注的编程方法,它将通用需求功能从不相关类之中分离出来;同时,能够使得很多类共享一个行为,一旦行 为发生变化,不必修改很多类,只要修改这个行为就可以。
    Interceptor将很多功能从我们的Action中独立出来,大量减少了我们Action的代码,独立出来的行为具有很好的重用性。XWork、 WebWork的许多功能都是有Interceptor实现,可以在配置文件中组装Action用到的Interceptor,它会按照你指定的顺序,在 Action执行前后运行。Interceptor在框架中的应用如下图所示:
    当你提交对Aciton(默认是.action结尾的Url)的请求时,ServletDispatcher会根据你的请求,去调度并执行相应的 Action。在Action执行之前,调用被 Interceptor截取,Interceptor在Action执行前后运行。


2. Interceptor的原理
    下面我们来看看Interceptor是如何实现在Action执行前后调用的:
    Action和Interceptor在框架中的执行,是由ActionInvocation对象调用的。它是用方法:String invoke() throws Exception;来实现的,它首先会依次调用Action对应的Interceptor,执行完成所有的Interceptor之后,再去调用 Action的方法,代码如下:
  if (interceptors.hasNext()) {
    Interceptor interceptor 
= (Interceptor) interceptors.next();
    resultCode 
= interceptor.intercept(this);
    }
 else {
       
if (proxy.getConfig().getMethodName() == null{
    resultCode 
= getAction().execute();
    }
 else {
        resultCode 
= invokeAction(getAction(), proxy.getConfig());
      }

    }
它会在拦截器栈中遍历Interceptor,调用Interceptor的方法:
    String intercept(ActionInvocation invocation) throws Exception;。
    我们一直都提到,Interceptor是在Action前后执行,可是从上面的代码我们看到的却是执行完所有Interceptor的intercept()方法之后再去调用我们的Action。“在Action前后执行”是如何实现的呢?我们来看看抽象类
AroundInterceptor的intercept()实现:
    
public String intercept(ActionInvocation invocation) throws Exception {
        String result 
= null;

        before(invocation);
        result 
= invocation.invoke();
        after(invocation, result);

        
return result;
    }
原来在intercept()方法又对ActionInvocation的invoke()方法进行递归调用,ActionInvocation循环嵌套 在intercept()中,一直到语句result = invocation.invoke();执行结束,即:Action执行完并返回结果result,这时Interceptor对象会按照刚开始执行的 逆向顺序依次执行结束。这样before()方法将在Action执行前调用,after()方法在Action执行之后运行。

3. 系统Interceptor介绍
    <interceptors>
            <interceptor name="timer" class="com.opensymphony.xwork.interceptor.TimerInterceptor"/>
            <interceptor name="logger" class="com.opensymphony.xwork.interceptor.LoggingInterceptor"/>
            <interceptor name="chain" class="com.opensymphony.xwork.interceptor.ChainingInterceptor"/>
            <interceptor name="static-params" class="com.opensymphony.xwork.interceptor.StaticParametersInterceptor"/>
            <interceptor name="params" class="com.opensymphony.xwork.interceptor.ParametersInterceptor"/>
            <interceptor name="model-driven" class="com.opensymphony.xwork.interceptor.ModelDrivenInterceptor"/>
            <interceptor name="component" class="com.opensymphony.xwork.interceptor.component.ComponentInterceptor"/>
            <interceptor name="token" class="com.opensymphony.webwork.interceptor.TokenInterceptor"/>
            <interceptor name="token-session" class="com.opensymphony.webwork.interceptor.TokenSessionStoreInterceptor"/>
            <interceptor name="validation" class="com.opensymphony.xwork.validator.ValidationInterceptor"/>
            <interceptor name="workflow" class="com.opensymphony.xwork.interceptor.DefaultWorkflowInterceptor"/>
            <interceptor name="servlet-config" class="com.opensymphony.webwork.interceptor.ServletConfigInterceptor"/>
            <interceptor name="prepare" class="com.opensymphony.xwork.interceptor.PrepareInterceptor"/>
            <interceptor name="conversionError" class="com.opensymphony.webwork.interceptor.WebWorkConversionErrorInterceptor"/>
            <interceptor-stack name="defaultStack">
                <interceptor-ref name="static-params"/>
                <interceptor-ref name="params"/>
                <interceptor-ref name="conversionError"/>
            </interceptor-stack>
            <interceptor-stack name="validationWorkflowStack">
                <interceptor-ref name="defaultStack"/>
                <interceptor-ref name="validation"/>
                <interceptor-ref name="workflow"/>
            </interceptor-stack>
        </interceptors>
    这些都时有框架提供的默认的Interceptor,更详细的可以参考webwork文档。
   
4. 自定义Interceptor
    (1)创建一个自己需要的Interceptor类,它必需实现com.opensymphony.xwork.interceptor.Interceptor接口,在Interceptor的intercept方法里面完成拦截器的处理逻辑;
    (2)在配置文件(xwork.xml)中申明这个Interceptor类,它放在标签<interceptor />中,同是<interceptor />标签嵌入在<interceptors />标签内部。
    (3)创建Interceptor栈,使用标签:<interceptor-stack  />,让一组Interceptor可以按次序调用。(可选)
    (4)指定Action所要用到的Interceptor(前面申明过的),可以用<interceptor-ref />或<default-interceptor-ref />标签。前面的标签指定某个Action所用到的Interceptor,如果Action没有被用<interceptor-ref />指定Interceptor,它将使用<default-interceptor-ref />指定的Interceptor。
    
5. Intercepter的Unit测试
     (1)首先配置Interceptor的测试环境(我理解就是模拟一个Action,通过模拟的Action启动Interceptor,模拟的Action可以不做任何的业务逻辑处理,这样就可以测试Interceptor的工作情况)
     (2)测试Interceptor
    
附录1:拦截器代码

public class SecurityInterceptor implements Interceptor {
   
    
private static Log log = LogFactory
                .getLog(SecurityInterceptor.
class);

    
public void destroy() {
      
        log.info(
">>> 销毁拦截器");
    }


    
public void init() {
      
        log.info(
">>> 初始化拦截器");
    }


    
public String intercept(ActionInvocation invocation) throws Exception {

 
//添加拦截器处理逻辑
 
        
return "";
    }


}


附录2: 配置拦截器
<?xml version="1.0" encoding="UTF-8"?>


<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.1.1//EN" "http://www.opensymphony.com/xwork/xwork-1.1.1.dtd">


<xwork>
   
    <include file="webwork-default.xml"/>
   
    <package name="default" extends="webwork-default">
       
        <!-- 声明拦截器 -->
        <interceptors>
            <interceptor name="security" class="cn.geocoding.gb.web.filter.SecurityInterceptor"/>
        </interceptors>


       
  
        <action name="searchAddressElement" class="cn.geocoding.gb.web.action.datamaintain.SearchAddressElementAction">
         <result name="success" type="dispatcher">/pages/datamaintain/addressElementList.jsp</result>
         <!-- 拦截器 -->
         <interceptor-ref name="security"/>
         <interceptor-ref name="params"/>
        </action>


    </package>
</xwork>

附录3: 配置Intercepter的Unit测试环境
public class TestConfigrationProvider implements ConfigurationProvider {

    
private String action;
   
    
private String packageName;
   
    
/* (non-Javadoc)
     * @see com.opensymphony.xwork.config.ConfigurationProvider#destroy()
     
*/

    
public void destroy() {
       

    }


    
/* (non-Javadoc)
     * @see com.opensymphony.xwork.config.ConfigurationProvider#
     * init(com.opensymphony.xwork.config.Configuration)
     
*/

    
public void init(Configuration configurationManager)
                                    
throws ConfigurationException {
      
        PackageConfig defaultPackageConfig 
= new PackageConfig();
        HashMap results 
= new HashMap();
        List
<InterceptorMapping> interceptors =
            
new ArrayList<InterceptorMapping>();
        interceptors.add(
new InterceptorMapping("security",
                
new SecurityInterceptor()));
        ActionConfig tokenActionConfig 
= new ActionConfig(null,
                BaseMockActionTest.
classnull,
                results, interceptors);
        defaultPackageConfig.addActionConfig(action, tokenActionConfig);
        configurationManager.addPackageConfig(packageName,defaultPackageConfig);
    }


    
/* (non-Javadoc)
     * @see com.opensymphony.xwork.config.ConfigurationProvider#needsReload()
     
*/

    
public boolean needsReload() {
        
return false;
    }


    
/**
     * 
@return Returns the action.
     
*/

    
public String getAction() {
        
return action;
    }


    
/**
     * 
@param action The action to set.
     
*/

    
public void setAction(String action) {
        
this.action = action;
    }


    
/**
     * 
@return Returns the packageName.
     
*/

    
public String getPackageName() {
        
return packageName;
    }


    
/**
     * 
@param packageName The packageName to set.
     
*/

    
public void setPackageName(String packageName) {
        
this.packageName = packageName;
    }

}

参考文献:

http://www.opensymphony.com/webwork/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值