Spring Extension (4) — AOP based Interceptor for Controller

场景:

SpringMVC HandlerInterceptor只能提供基于http url requestAOP拦截,如果Controller中某些RequestMapping handler method需要权限才能访问----当然可以通过handler method对应urlHandlerInterceptor来完成这个要求,这样就比较麻烦:HandlerInterceptor配置文件中设置了一堆的url字符串,而且不停的增长、膨胀。。。

如果通过能用handler method 级别的aop来完成这个功能,只需要在handler method上添加一个Annotation表示当前方法需要权限验证即可,然后通过 AOP Advice来做这些判断。

代码:

1、定义Annotation

  /**
   * true:user should be authed before the action.false:needn't.
   */
  @Documented
  @Target({ElementType.TYPE,ElementType.METHOD})
  @Retention(RetentionPolicy.RUNTIME)
  public @interface AuthRequired {
      public boolean value() default true; 
  }


2、在目标方法上定义:

@Controller
@RequestMapping("/")
public class UserController{
	@RequestMapping(value="/demo")
  @AuthRequired //http访问表示当前方法,需要用户先登陆
	public @ResponseBody Map<String, String>> demo(@RequestAttribute("loginUserId") long loginUserId){
		return Collections.emptyMap();
	}
}

3AOP定义

1Advice


  /**
   * verify whether user is authed
   * 
   */
  @Component("authAdvice")
  public class AuthAdvice implements MethodBeforeAdvice {
      private static final Logger logger = LoggerFactory.getLogger(AuthAdvice.class);
      @Override
      public void before(Method method, Object[] args, Object target) throws Throwable {
          HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
                  .getRequestAttributes()).getRequest();//获取request
          
          Long userId = (Long) request.getAttribute("loginUserId");
          
          AuthRequired needAuth = AnnotationUtils.findAnnotation(method, AuthRequired.class);
          if (needAuth != null&&needAuth.value) {
              if(userId == null)
              	throw new NotLoginException("not login");
          }        
      }


2、PointcutAdvisor

  /**
   * aspect pointcut for the controller and verifying whether is logined.
   * 
   */
  @Component("authAdvisor")
  public class AuthPointcutAdvisor extends StaticMethodMatcherPointcutAdvisor {
      /**
       * must be the {@link RequestMapping}
       */
      @Override
      public boolean matches(Method method, Class<?> targetClass) {
          RequestMapping mapping = AnnotationUtils.findAnnotation(method, RequestMapping.class);
          if (mapping != null) {// 只拦截RequestMapping修饰的方法
              return true;
          }
          return false;
      }
      /**
       * must be {@link Controller}
       */
      public ClassFilter getClassFilter() {
          return new ClassFilter() {
              @Override
              public boolean matches(Class<?> clazz) {
                  return AnnotationUtils.isAnnotationDeclaredLocally(Controller.class, clazz);
                 
              }
          };
      }
  
      @Resource(name = "authAdvice")
      public void setAdvice(Advice advice) {
          super.setAdvice(advice);
      }
  }



4、启用AOP


  <!-- 必须在MethodValidationPostProcessor之前初始化,否则在authAdvice执行之前会优先执行Spring Validation,导致权限认证服务执行之前就执行parameter validation 操作-->
  	<bean id="autoProxyCreator"  class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean>
  <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
  	<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor" depends-on="autoProxyCreator"/>

注:

Spring Request Scope

SpringMVC中,如果使用DispatcherServlet初始SpringMVC容器,那么spring web application context默认启用request scope。故((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();能够正常获取HttpServletRequest对象。


Spring AOP

DefaultAdvisorAutoProxyCreator 比使用AspectJSchema-based AOP的好处是能够获取当前被拦截方法method对象相关的信息,例如method 上的Annotationargs上的annotation



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值