场景:
在《Spring Extension (2) — Annotation RequestAttribute for Controller method Parameter Injection》中定义了UserInterceptor,默认拦截所有http 请求,如果只拦截/demo, /demo2 的请求呢?
可以使用这种方式
<bean class="">
<property name="interceptors">
<list>
<bean class="">
<constructor-arg index="0">
<list>
<value>/demo<value>
<value>/demo1<value>
<list>
</constructor-arg>
<constructor-arg index="1">
<ref bean="userInterceptor"/>
</constructor-arg>
</bean>
</list>
</property>
</bean>
或者
<bean class="">
<property name="interceptors">
<list>
<bean class="">
<property name="matchUrls">
<list>
<value>/demo<value>
<value>/demo1<value>
</list>
</property>
</bean>
</list>
</bean>
在UserInterceptor中定义需要拦截的url: matchUrls,然后编码判断拦截逻辑。。。
如果/demo1,/demo 是由同一个Controller处理,而且以后可能新的request url: /test ,也是由相同的Controller处理,更简单的方式是在Controller上声明相应的HandlerInterceptor。
例如:
@Controller
@RequestMapping("/")
@HandlerInterceptors({ })
public class UserController{
// detail RequestMapping({"/demo", "/demo1","/test"}
}
代码:
1、定义Annotation:
/**
* spring handler interceptor configuration by annotation
*/
@Documented
@Target({})
@Retention()
public @interface HandlerInterceptors {
/**
* find spring bean instance by the class type
*/
Class<? extends HandlerInterceptor>[] value();
}
2、在目标类定义:
@Controller
@RequestMapping("/")
@HandlerInterceptors({ })
public class UserController{
// detail RequestMapping({"/demo", "/demo1","/test"}
}
3、在Spring中关联Interceptor与Controller:
/**
* assemble the {@link HandlerInterceptor}s by Annotation {@link Interceptors}.
*/
public class CustomAnnotationHandlerMapping extends DefaultAnnotationHandlerMapping {
private final static Logger logger = (CustomAnnotationHandlerMapping .class);
@Override
protected HandlerExecutionChain getHandlerExecutionChain(Object handler,HttpServletRequest request){
HandlerExecutionChain chain = (handler,request);
HandlerInterceptor[] interceptors = detectInterceptors(().getClass());
(interceptors);
return chain;
}
/**
* find {@link HandlerInterceptor}s present on the {@link Controller} via the {@code HandlerInterceptor}
* @param handlerClass
* @return
*/
protected HandlerInterceptor[] detectInterceptors(Class<?> handlerClass) {
HandlerInterceptors interceptorAnnot = (handlerClass, );//custom annotation: HandlerInterceptors
List<HandlerInterceptor> interceptors = new ArrayList<HandlerInterceptor>();
if (interceptorAnnot != null) {
Class<? extends HandlerInterceptor>[] interceptorClasses = ();// interceptors for the handlerClass
if (interceptorClasses != null) {
for (Class<? extends HandlerInterceptor> interceptorClass : interceptorClasses) {
if (!(interceptorClass)) {
raiseIllegalInterceptorValue(handlerClass,interceptorClass);
}
(().getBean(interceptorClass));
}
}
}
return (new HandlerInterceptor[0]);
}
protected void raiseIllegalInterceptorValue(Class handlerClass,Class interceptorClass) {
throw new IllegalArgumentException(interceptorClass + " specified on "
+ handlerClass + " does not implement " + ());
}
}
4、启用自定义的HandlerMap类
将
<bean class="">
<property name="interceptors">
<list>
<ref bean="userInterceptor " />
</list>
</property>
</bean>
修改为:
<bean class=" ">
......
</bean>
使用这种方式的好处就是能够统一拦截同一个Controller对应的所有http url request,而且这些url没有任何规则可言。缺点是忽略Controller对应的某个请求比较麻烦,如果HandlerInterceptor只是用来执行通用的计算逻辑,这个缺点可以忽略。