zoukankan      html  css  js  c++  java
  • 项目中AOP的实例应用

    其中包括了权限管理、表单验证、事务管理、信息过滤、拦截器、过滤器、页面转发等等。

    公司项目的应用:(涉及用户验证登录以及用户是否有管理员权限、心理用户权限等),还有涉及的其他日志管理代码就不一一举例了;

    /**
     * 登录拦截器(登录判断)
     * @author alex
     *
     */
    public class LoginInterceptor extends HandlerInterceptorAdapter {
    
        @Autowired
        private UserService userService;
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            if (handler instanceof HandlerMethod) {
                HandlerMethod handlerMethod = (HandlerMethod) handler;
                //check login
                Login login = handlerMethod.getMethodAnnotation(Login.class);
                if (null == login) {
                    return true;
                }
                int userId = 0;
                String uid = CookieUtil.getValueByName(request, CookieUtil.SESSION_USER);
                if(NumberUtils.isNumber(uid)){
                    userId = Integer.valueOf(uid);
                }
                if(userId==0 || !userService.isLogined(userId, CookieUtil.getValueByName(request, CookieUtil.SESSION_ID))){
                    response.sendRedirect("/login");
                    return false;
                }
                //set user info
                User user = userService.getUserById(userId);
                request.setAttribute("userSession", user);
                request.setAttribute("loginUsername",user.getUsername());
                request.setAttribute("loginUserId",user.getId());
                //******* 是内部测试的心理账户
                request.setAttribute("psychologyUser", user.getType == *** || "*******".equals(user.getCellphone()));
                //check admin permission
                Admin admin = handlerMethod.getMethodAnnotation(Admin.class);
                if (admin!=null && !user.isAdmin()) {
                    response.sendRedirect("/error/no_permission");
                    return false;
                }
                return true;
            }
            return true;
        }
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
                throws Exception {
        }
    }
    /**
     * 登录注解
     * @author Alex
     *
     */
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Login {
        int value() default 0;
    }
    
    
    /**
     * 管理员注解
     * @author Alex
     *
     */
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Admin {
        int value() default 0;
    }

    一般情况下,对来自浏览器的请求的拦截,是利用Filter实现的,这种方式可以实现Bean预处理、后处理。 
    Spring MVC的拦截器不仅可实现Filter的所有功能,还可以更精确的控制拦截精度。 

    Spring为我们提供了org.springframework.web.servlet.handler.HandlerInterceptorAdapter这个适配器,继承此类,可以非常方便的实现自己的拦截器。他有三个方法:

    1. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)    
    2.         throws Exception {    
    3.         return true;    
    4.     }    
    5.     public void postHandle(    
    6.             HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)    
    7.             throws Exception {    
    8.     }    
    9.     public void afterCompletion(    
    10.             HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)    
    11.             throws Exception {    
    12.     }    


    分别实现预处理、后处理(调用了Service并返回ModelAndView,但未进行页面渲染)、返回处理(已经渲染了页面) 

    preHandle预处理回调方法,实现处理器的预处理(如登录检查),第三个参数为响应的处理器;

         返回值:true表示继续流程(如调用下一个拦截器或处理器);

                 false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应;

    postHandle后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。

    afterCompletion整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中preHandle返回true的拦截器的afterCompletion

    AOP相关配置:

    <mvc:interceptors>
            <mvc:interceptor>
                <mvc:mapping path="/**" />
                <mvc:exclude-mapping
                    path="/css/**,/js/**,/img/**,/fonts/**,/stylesheets/**,/javascripts/**,/images/**,/ueditor/**" />
                <bean class="com.zhaozhi.writing.service.interceptor.AssetsInterceptor" />
            </mvc:interceptor>
            <mvc:interceptor>
                <mvc:mapping path="/**" />
                <mvc:exclude-mapping
                    path="/css/**,/js/**,/img/**,/fonts/**,/stylesheets/**,/javascripts/**,/images/**,/ueditor/**" />
                <bean class="com.zhaozhi.writing.service.interceptor.LoginInterceptor" />
            </mvc:interceptor>
            <mvc:interceptor>
                <mvc:mapping path="/**" />
                <mvc:exclude-mapping
                    path="/css/**,/js/**,/img/**,/fonts/**,/stylesheets/**,/javascripts/**,/images/**,/ueditor/**" />
                <bean class="com.zhaozhi.writing.service.interceptor.RoleInterceptor" />
            </mvc:interceptor>
            <mvc:interceptor>
                <mvc:mapping path="/**" />
                <mvc:exclude-mapping
                    path="/css/**,/js/**,/img/**,/fonts/**,/stylesheets/**,/javascripts/**,/images/**,/ueditor/**" />
                <bean class="com.zhaozhi.writing.service.interceptor.HitlogInterceptor" />
            </mvc:interceptor>
        </mvc:interceptors>
  • 相关阅读:
    Spark源码走读6——Shuffle
    Spark源码走读5——Storage
    使用Gradle构建Android应用的渠道包
    轻松搞定面试中的二叉树题目
    QT中使用微软Speech API实现语音识别
    QT 相关资源(书籍、论坛、博客等。。。)整理...
    使用Cscope阅读大型工程Linux内核的源代码教程
    搭建一个免费的,无限流量的Blog----github Pages和Jekyll入门
    RSA算法原理(二)
    RSA算法原理(一)
  • 原文地址:https://www.cnblogs.com/yzf666/p/7544891.html
Copyright © 2011-2022 走看看