关键字: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”