Spring Extension (4) — AOP based Interceptor for Controller
来源:互联网 发布:岛风go软件打不开 编辑:程序博客网 时间:2024/04/29 01:04
场景:
SpringMVC HandlerInterceptor只能提供基于http url request的AOP拦截,如果Controller中某些RequestMapping handler method需要权限才能访问----当然可以通过handler method对应url的HandlerInterceptor来完成这个要求,这样就比较麻烦: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();}}
3、AOP定义
1、Advice
/** * 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 比使用AspectJ和Schema-based AOP的好处是能够获取当前被拦截方法method对象相关的信息,例如method 上的Annotation、args上的annotation等
- Spring Extension (4) — AOP based Interceptor for Controller
- Spring Extension (3) — Annotation based Controller HandlerInterceptor
- Spring Extension (2) — Annotation RequestAttribute for Controller method Parameter Injection
- Spring Extension (1) — BeanPostProcessor based Logger Injection
- Spring入门(Schema-based AOP其一)
- Spring入门(Schema-based AOP其二)
- Spring入门(Schema-based AOP其三)
- Spring入门(Schema-based AOP其四)
- Spring AOP Interceptor transaction is not working
- spring mvc interceptor 与 aop 执行顺序
- Spring AOP代理controller类
- spring Aop拦截controller方法
- Spring AOP代理Controller层
- spring aop学习--拦截controller
- 使用Spring(11)使用Spring进行面向切面编程(AOP)Schema-based AOP support
- [Spring aop 配置] <aop:config> Schema-based AOP support
- spring aop 拦截spring mvc controller
- Spring Aop实现——Annotation方式(注解式)and Schema-based式(xml配置)
- keil c编译器报warning: #870-D: invalid multibyte character sequence解决办法
- IPVS实现分析
- 异常(收藏)
- AOV网络
- Android:Gson通过借助TypeToken获取泛型参数的类型的方法
- Spring Extension (4) — AOP based Interceptor for Controller
- fpga的配置
- 宏定义与枚举
- 查看MySQL引擎支持类型及查看表当前引擎类型
- php基础学习
- 谈Window Vista/7如何调整硬盘分区,如何扩充系统盘
- hello_world-2.3之简单设备驱动模型(三)---添加设备属性文件
- 数据库内外连接、自连接
- java上机 第十五周 任务一