spring MethodInterceptor 與 反射

關鍵字:java spring攔截器,實現MethodInterceptor 接口 反射 AOP

最近項目中需要一個功能,就是說前臺展示分頁效果需要特定的css效果,只要是前臺請求,都要統一的樣式,考慮再三感覺用攔截器好實現,而且改一個樣式,不會影響後臺,但是攔截器需要攔截到請求地址所附帶的參數,去除參數值,然後動態的改變參數值,並且參數值是一個實體類。動態改變實體類的屬性以前從沒做過,百度了一下發現反射可以實現。廢了一天時間搞了出來。代碼如下!

攔截器業務邏輯代碼


    public class ForePageFilter implements MethodInterceptor {


    @Override
    public Object invoke(MethodInvocation arg0) throws Throwable {
    // TODO Auto-generated method stub
    Class<?>[] classType = arg0.getMethod().getParameterTypes();//截取參數值
    Object[] args = arg0.getArguments();
        //Type[] types = arg0.getMethod().getGenericParameterTypes();//截取參數類型
        Integer paramnum = classType.length;
        for(int i = 0;i < paramnum; i++){
          System.out.println(classType[i]==PageQuery.class);
         if(classType[i] == PageQuery.class){
             PageQuery query = (PageQuery)args[i];
             classType[i].getDeclaredField("style").set(query, PageView.Style.FORE);//java反射機制 動態設置值
          }
        }
        return arg0.proceed();

這裏用到的攔截器是MethodInterceptor ,如果用HandlerInterceptorAdapter可能會比較麻煩,因爲還要動態改變參數的值。
此處需要獲取實體參數的值,來動態改變,即重新爲屬性賦值,在這裏攔截器截取到的參數arg0可以獲取所有參數以及參數的值和屬性,賦值是重點,所有需要截取的是值,並非類型,這點很重要,不然起不到重新賦值的作用,第一次我就是獲取了屬性,結果搞了好久才搞成功。 arg0.getMethod()返回類型是method,可參考jdk的API文檔,其中getGenericParameterTypes()是獲取類型,如果要改變參數的值,需要用到getParameterTypes()方法。獲取到值後,遍歷參數,找到你要改變值得參數,classType[i].getDeclaredField(“style”)返回的是你要改變參數的屬性字段,可參考jdk的API文檔field。然後用set重新賦值即可。

配置文件中加AOP配置代碼如下

    <!-- 前臺分頁效果處理 -->
        <bean id="controllerMethodInterceptor" class="net.tuxun.customer.module.common.ForePageFilter"/>
        <!-- 方法攔截器(攔截Controller包中的所有被RequestMapping註解的方法) MethodInterceptor     net.tuxun.customer.module.*.web -->
    <aop:config proxy-target-class="true">
        <aop:pointcut id="controllerMethodPointcut" expression="execution(* net.tuxun.customer.module.*.web..*(..)) and @annotation(org.springframework.web.bind.annotation.RequestMapping)"/>
        <aop:advisor advice-ref="controllerMethodInterceptor" pointcut-ref="controllerMethodPointcut" />
        </aop:config>

spring mvc實現接口

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class InputExcelFilter implements HandlerInterceptor {

  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
      throws Exception {
    System.out.println("a");
    return true;
  }

  @Override
  public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
      ModelAndView modelAndView) throws Exception {
    System.out.println("b");

  }

  @Override
  public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
      Object handler, Exception ex) throws Exception {
    System.out.println("c");

  }
}

spring mvc配置文件

    <mvc:interceptors>  
        <!-- 使用bean定義一個Interceptor,直接定義在mvc:interceptors根下面的Interceptor將攔截所有的請求 -->  
        <!-- <bean class="net.tuxun.customer.common.InputExcelFilter"/>   -->
        <mvc:interceptor> 
            <!-- 攔截的路徑 -->
            <mvc:mapping path="/excel/import/xsMonitorCorpList.do"/>
            <!-- 定義在mvc:interceptor下面的表示是對特定的請求才進行攔截的 -->  
            <bean class="net.tuxun.customer.common.InputExcelFilter"/>  
        </mvc:interceptor>  
    </mvc:interceptors>    

配置前要引入aop的文件。
xmlns:aop=”http://www.springframework.org/schema/aop,
http://www.springframework.org/schema/aop,
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章