Struts2-MethodFilterInterceptor

阅读更多

一,要配置struts.xml文件。

  
      
          
              
                world  
              
              
              
                
              
                test,abc  
              
          
          
            /methodFilterResult.jsp  
              
                
              
                abc  
              
          
      
  

要点:1,默认情况下,拦截器会拦截Action中的所有方法,这里不包括setter或getter方法。这时就可以使用方法过滤拦截器来拦截指定的方法,这是一种更加细化的拦截器的配置方式。它可以细化到拦截具体的某个方法,而不是拦截某个Action,因为拦截Action是一种粗粒度的实现方式。

           2,使用includeMethods指明拦截器所要拦截的方法,使用excludeMethods指明拦截器不再拦截的方法。这里excludeMethods和includeMethods是在MethodFilterInterceptor类中定义的成员变量

           3,只要includeMethods进来的方法就一定会被拦截,而不管是否已经把它excludeMethods在外了。也就是说,includeMethods的优先级要高于excludeMethods

           4,也可以使用在上面定义拦截器的时候指定全局性过滤的方法。区别就是对方法的过滤有全局性和局部性区分,而当发生冲突时,则依照“就近原则”以局部性的配置为准。(所谓的发生冲突,指的是类似于全局中有一个includeMethods配置,而局部中也有一个includeMethods配置!)

           5,还有一种情况——假设全局性过滤定义为test,而在局部性过滤中定义为test。这种情况下,前者将生效,即拦截Action中的test()方法。因为全局中配置的是拦截,局部中配置的是不拦截,二者并没有发生冲突,所以仍是以includeMethods优先级高。(可以认为在局部的配置中,已经隐含地把test继承过来了!)

           6,这里衡量的所谓拦截到与否,主要可以通过查看控制台输出的语句,以判断是否执行到该拦截器内部。

 

二,然后写实现了Interceptor接口的自定义拦截器MyInterceptor11.java。

package com.jadyer.interceptor;  
  
import com.opensymphony.xwork2.ActionInvocation;  
import com.opensymphony.xwork2.interceptor.Interceptor;  
  
/** 
 * 实现Interceptor接口的自定义拦截器 
 * @see 【这种方式不太常用】 
 */  
@SuppressWarnings("serial")  
public class MyInterceptor11 implements Interceptor {  
    //这里的属性名要与struts.xml配置的中的name值相同  
    //然后Struts2会自动将struts.xml中配置的world值赋值到这里的hello属性中  
    //当然,前提是要提供setter和getter方法,只要符合JavaBean的要求即可  
    private String hello;  
  
    public String getHello() {  
        return hello;  
    }  
    public void setHello(String hello) {  
        this.hello = hello;  
    }  
  
    /** 
     * 初始化时执行的方法 
     */  
    public void init() {  
        System.out.println("------MyInterceptor11 init method invoked------");  
        System.out.println(hello);  
    }  
    /** 
     * 销毁时执行的方法 
     */  
    public void destroy() {  
        System.out.println("------MyInterceptor11 destroy method invoked------");  
    }  
  
    //每执行一次action请求,这里的intercept()方法都会被执行一次  
    public String intercept(ActionInvocation invocation) throws Exception {  
        System.out.println("------MyInterceptor11 invoked begin------");  
        //调用invoke()方法  
        //如果还有下一个拦截器的话,就执行下一个拦截器  
        //如果没有下一个拦截器的话,便执行Action中的方法  
        String result = invocation.invoke();  
        System.out.println("------MyInterceptor11 invoked finish------");  
        return result;  
    }  
}

要点:1,Struts2中的拦截器是用来拦截Action的,它相当于入口和出口一样,把Action的相关方法包裹在中间。拦截器栈相当于一串拦截器,用来共同地拦截某一个Action,拦截的顺序是按照配置的顺序执行的,但是结束却是按照配置的倒序执行的

           2,也就是说首先会进入第一个拦截器,出来后再进入第二个,依次类推,最后进入Action的execute()方法。当execute()执行后,再按照相反的顺序,先回到第二个拦截器,再回到第一个,最后才回到结果视图。因此invoke()就是用来判断,若还有下一个拦截器,就调用下一个,否则直接跳到Action的execute()方法

 

三,也可以写继承了AbstractInterceptor类的自定义拦截器。

package com.jadyer.interceptor;

import java.util.Map;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
/**
 * 继承AbstractInterceptor类的自定义拦截器
 * @see 【这种方式比较常用】
 * @see 继承AbstractInterceptor之后,就不需要再去实现init()和destroy()方法了
 * @see 所以实际应用中,更多的时候还是继承AbstractInterceptor,而不是实现Interceptor
 * @see ------------------------------------------------------------------------------------------------------------
 * @see 也可以用下面这种方式来配置
 * @see 
 * @see 		
 * @see 			
 * @see 			
 * @see 				
 * @see 				
 * @see 			
 * @see 		
 * @see 		
 * @see 
 * @see ------------------------------------------------------------------------------------------------------------
 */
@SuppressWarnings("serial")
public class MyInterceptor extends AbstractInterceptor {
	@Override
	public String intercept(ActionInvocation invocation) throws Exception {
		System.out.println("------------ScriptHitInterceptor invoked begin------------");
		
		//获取请求的方法名,得到的方法名不包含括号,例如methodName=preLoginCheck
		System.out.println("获取请求方法:methodName=" + invocation.getInvocationContext().getName());
		
		//获取请求的参数名和参数值
		Map parameters = invocation.getInvocationContext().getParameters();
		for(Map.Entry entry : parameters.entrySet()){
			//借助parameters根据参数名获取参数值对象,其实得到的参数值对象是一个字符串数组,该数组第一个元素即真实参数值
			System.out.println("获取请求参数:" + entry.getKey() + "=" + ((String[])parameters.get(entry.getKey()))[0]);
			//修改下参数值
			parameters.put(entry.getKey(), new String[]{"jadyer" + ((String[])parameters.get(entry.getKey()))[0]});
		}
		
		//填加一个参数,这里指定其值为jadyer
		//Struts2之所以采用字符串数组的方式,或许是为了应对参数名或参数值相同的情况吧
		parameters.put("myname", new String[]{"jadyer"});
		
		//再次获取参数名和参数值
		for(Map.Entry entry : parameters.entrySet()){
			System.out.println("重新获取参数:" + entry.getKey() + "=" + ((String[])parameters.get(entry.getKey()))[0]);
		}
		
		//也可以通过HttpServletRequest获取真实参数值,不过它获取到的是最原始的请求参数值,而非上面我们改动过的参数值
		//如果在Struts2的Action中通过ServletActionContext.getRequest().getParameter("fromBanner")获取参数值的话
		//那么后台获取到的也只是原始的请求参数值fromBanner=yes,而非fromBanner=jadyeryes
		for(Map.Entry entry : parameters.entrySet()){
			System.out.println("再次获取参数:" + entry.getKey() + "=" + ServletActionContext.getRequest().getParameter(entry.getKey()));
		}
		
		String result = invocation.invoke();
		System.out.println("------------ScriptHitInterceptor invoked finish------------");
		return result;
	}
}

 

四,还可以写继承了MethodFilterInterceptor拦截器类的自定义拦截器MyInterceptor33.java。

package com.jadyer.interceptor;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;

/**
 * 继承MethodFilterInterceptor的拦截器,即方法过滤的拦截器
 * @see 查看MethodFilterInterceptor的源码可知,它也是一个拦截器类,它继承了AbstractInterceptor
 * @see 观察它的类名,可以发现,它就是一个拦截某一个具体的方法的方法过滤拦截器
 * @see 而MethodFilterInterceptor类已经自动实现好了Intercept()方法
 * @see 实际上MethodFilterInterceptor类中的Intercept()方法真正执行的是它本身的一个doIntercept()抽象方法
 * @see 因此,我们想要拦截某一个方法的时候,只要继承MethodFilterInterceptor类,然后实现doIntercept()便OK
 */
@SuppressWarnings("serial")
public class MyInterceptor33 extends MethodFilterInterceptor {
	@Override
	protected String doIntercept(ActionInvocation invocation) throws Exception {
		System.out.println("------MyInterceptor33 invoked begin------");
		String result = invocation.invoke();
		System.out.println("------MyInterceptor33 invoked finish------");
		return result;
	}
}

要点:工作时经常碰到的是这种拦截器。

你可能感兴趣的:(Struts2)