为了对指定方法进行权限验证等操作,很多时候我们要采用aop或者interceptor的方式,一直对自定义注解+interceptor的拦截方式不是特别了解,今天入了一下门。
1、首先自定义一个注解,@Target(ElementType.METHOD)表示这个注解只能在METHOD上使用,@Retention(RetentionPolicy.RUNTIME) 表示运行时生效,剩下那个没啥用
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ParamCheck {
}
2、那么,怎么完成这个注解的具体逻辑呢。这里建议使用HandlerInterceptorAdapter来实现interceptor,因为如果使用坑爹的HandlerInterceptor的话,三个方法你都得显示的Overwrite一下
@Slf4j
public class ParamInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 1、Class.isAssignableFrom()作用与instanceof相似,
// 前者是用来判断一个类Class1和另一个类Class2是否相同或是另一个类的子类或接口
// 后者是用来判断一个对象实例是否是一个类或接口的或其子类子接口的实例
// 2、HandlerMethod及子类主要用于封装方法调用相关信息
// 简单点说我们可以通过这个类对象获得被调用方法的各种信息,如方法名、参数类型等
if(handler.getClass().isAssignableFrom(HandlerMethod.class)) {
//获得注解对象
ParamCheck paramCheck = ((HandlerMethod) handler).getMethodAnnotation(ParamCheck.class);
Method method = ((HandlerMethod) handler).getMethod();
//因为不再在dispatcher-servlet.xml配置<mvc:mapping path=>,所以会拦截所有的方法,这里需要判断方法是否被我们自定义的这个注释修饰
//这里可能有疑问就是既然拦截所有的方法,那不很影响效率么,我靠但是灵活呀大兄弟
if (paramCheck == null) {
log.debug("paramCheck == null");
return true;
}
log.debug(method.getName());
}
return true;
}
}
但是这里有个疑问,因为我也是之前没有研究过这里,就是说handler还会有其他的可能类型么,在什么情况下会传入其他的类型么,希望大牛能够解答
3、既然annotation和interceptor关联起来了,我们就可以使用注解了,很简单在方法上面加上就行了
@ParamCheck
@ResponseBody
@RequestMapping("hello")
public void hello() {
String result = "hello";
log.debug(result);
}
4、当然,我们还需要在dispatcher-servlet.xml里配置使interceptor生效
<mvc:interceptors>
<bean class="com.mmears.statistics.annotation.ParamInterceptor"></bean>
</mvc:interceptors>
完事~妥妥的