CRUD工程师---拦截器的使用

拦截器 :是在面向切面编程的就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作。

过滤器:是在javaweb中,你传入的request、response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的action进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者 struts的action前统一设置字符集,或者去除掉一些非法字符。

 两者的本质区别:拦截器是基于Java的反射机制的,而过滤器是基于函数回调。从灵活性上说拦截器功能更强大些,Filter能做的事情,他都能做,而且可以在请求前,请求后执行,比较灵活。Filter主要是针对URL地址做一个编码的事情、过滤掉没用的参数、安全校验(比较泛的,比如登录不登录之类),太细的话,还是建议用interceptor。不过还是根据不同情况选择合适的。

拦截器应用场景:

权限检查:如是否已经登录,或则对某些数据具有增删改查等权限;

日志记录:可以记录请求信息的日志,以便进行信息监控,信息统计等;

性能监控:慢日志等。

一般拦截这个情况,我会使用shiro自带的或者在里面再来一个过滤器,所以这方面比较薄弱

第一拦截器,这个拦截器要实现HandlerInterceptor接口,这个接口里有四大方法,preHandle是在请求controllor前调用,postHandler在调用Controller方法之后、视图渲染之前调用,afterCompletion是在渲染视图完成之后使用,afterConcurrentHandlingStarted方法用来处理异步请求。

在拦截器配置类class上使用要注解@Configuration,这里要实现接口WebMvcConfigurer。
重写addInterceptors方法,这个方法里呢要配置两项,一个是拦截器,一个是拦截器的URL。

处理器拦截器(HandlerIntercepto):

public interface HandlerInterceptor {

   /**
     * 预处理回调方法,实现处理器的预处理(如检查登陆),第三个参数为响应的处理器,自定义Controller
     * 返回值:true表示继续流程(如调用下一个拦截器或处理器);false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应;
   */
    boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception;

   /**
     * 后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。
   */
    void postHandle(
            HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
            throws Exception;

   /**
    * 整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中
   */
    void afterCompletion(
            HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception;

}

拦截适配器(初始化了HandlerIntercepto的相应方法,不用都实现):

如果只需要实现三个回调方法中的某些方法,可以继承该抽象类,该抽象类相当于对HandlerIntercepto进行简单实现。如记录日志,需要在程序跑完后,记录相应的增删改查,只需实现afterConcurrentHandlingStarted()方法。

 

public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor {

    /**
     * 默认是true
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        return true;
    }

    /**
     * This implementation is empty.
     */
    @Override
    public void postHandle(
            HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
            throws Exception {
    }

    /**
     * This implementation is empty.
     */
    @Override
    public void afterCompletion(
            HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
    }

    /**
     * 不是HandlerInterceptor的接口实现,是AsyncHandlerInterceptor的,AsyncHandlerInterceptor实现了HandlerInterceptor
     */
    @Override
    public void afterConcurrentHandlingStarted(
            HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
    }

}

运行流程

1.流程顺序:

    1.1拦截器执行顺序按照Spring配置文件中定义的顺序执行;

    1.2首先按照执行顺序执行所有拦截器的preHandle()方法【用于预处理等】,如果遇到返回值是false,则不会执行还未执行的拦截器,而是直接倒序执行afterCompletion()方法,如果为true,则依次执行剩下的拦截器;

    1.3如果所有拦截器的preHandle()方法返回值都为true,则执行相应的控制层接口(controller),如果在该接口中有异常抛出,则和preHandle()方法返回false一样,不会执行postHandle(),而是直接倒序执行afterCompletion()方法;

    1.4如果接口(controller)中业务逻辑执行完成(页面还未渲染数据),会倒序执行postHandle()方法,渲染完数据后,然后倒序执行afterCompletton()方法。

2.运行流程图:

 

 

 

posted @ 2020-06-09 22:55  smartcat994  阅读(162)  评论(0编辑  收藏  举报