關鍵字: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”