Spring Extension (3) — Annotation based Controller HandlerInterceptor

场景:

在《Spring Extension (2) — Annotation RequestAttribute for Controller method Parameter Injection中定义了UserInterceptor,默认拦截所有http 请求,如果只拦截/demo, /demo2 的请求呢?

可以使用这种方式

  <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
  		<property name="interceptors">
  			<list>
  				<bean class="org.springframework.web.servlet.handler.MappedInterceptor">
                                  <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="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
  		<property name="interceptors">
  			<list>
  				<bean class="com.xxoo.UserInterceptor">
                                  <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({ UserInterceptor.class })
public class UserController{
  // detail RequestMapping({"/demo", "/demo1","/test"}
}

代码:

1、定义Annotation

  /**
   * spring handler interceptor configuration by annotation
   */
  
  @Documented
  @Target({ElementType.TYPE})
  @Retention(RetentionPolicy.RUNTIME)
  public @interface HandlerInterceptors {
      /**
       * find spring bean instance by the class type
       */
      Class<? extends HandlerInterceptor>[] value();
  }

2、在目标类定义:

@Controller
@RequestMapping("/")
@HandlerInterceptors({ UserInterceptor.class })
public class UserController{
  // detail RequestMapping({"/demo", "/demo1","/test"}
}

3、在Spring中关联InterceptorController

/**
 * assemble the {@link HandlerInterceptor}s by Annotation {@link Interceptors}.
 */
public class CustomAnnotationHandlerMapping extends DefaultAnnotationHandlerMapping {
    private final static Logger logger = LoggerFactory.getLogger(CustomAnnotationHandlerMapping .class);
    @Override
    protected HandlerExecutionChain getHandlerExecutionChain(Object handler,HttpServletRequest request){
        HandlerExecutionChain chain = super.getHandlerExecutionChain(handler,request); 
        HandlerInterceptor[] interceptors = detectInterceptors(chain.getHandler().getClass());
        chain.addInterceptors(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 = AnnotationUtils.findAnnotation(handlerClass, HandlerInterceptors.class);//custom annotation: HandlerInterceptors
        List<HandlerInterceptor> interceptors = new ArrayList<HandlerInterceptor>();
        if (interceptorAnnot != null) {
          Class<? extends HandlerInterceptor>[] interceptorClasses = interceptorAnnot.value();// interceptors for the handlerClass
          if (interceptorClasses != null) {
            for (Class<? extends HandlerInterceptor> interceptorClass : interceptorClasses) {
              if (!HandlerInterceptor.class.isAssignableFrom(interceptorClass)) {
                raiseIllegalInterceptorValue(handlerClass,interceptorClass);
              }
              interceptors.add(this.getApplicationContext().getBean(interceptorClass));
            }
          }
        }
        return interceptors.toArray(new HandlerInterceptor[0]);
    }


    protected void raiseIllegalInterceptorValue(Class handlerClass,Class interceptorClass) {          
        throw new IllegalArgumentException(interceptorClass + " specified on "
            + handlerClass + " does not implement " + HandlerInterceptor.class.getName());
            
    }
}



4、启用自定义的HandlerMap

  <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
  		<property name="interceptors">
  			<list>
  				<ref bean="userInterceptor " />
  			</list>
  		</property>
  	</bean>


修改为:

 <bean class="com.xxoo.CustomAnnotationHandlerMapping ">
    ......
  </bean>


使用这种方式的好处就是能够统一拦截同一个Controller对应的所有http url request,而且这些url没有任何规则可言。缺点是忽略Controller对应的某个请求比较麻烦,如果HandlerInterceptor只是用来执行通用的计算逻辑,这个缺点可以忽略。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值