博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring拦截器
阅读量:5359 次
发布时间:2019-06-15

本文共 5793 字,大约阅读时间需要 19 分钟。

一.应用场景

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

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

  性能监控:慢日志等。

二.拦截器接口

  1.处理器拦截器(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;}

 

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

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

    注:该拦截器中多了一个afterConcurrentHandlingStarted()方法,该方法用于处理异步请求,当Controller中有异步请求方法的时候会触发该方法时,异步请求先支持preHandle、然后执行afterConcurrentHandlingStarted。异步线程完成之后执行preHandle、postHandle、afterCompletion。

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.运行流程图:

    2.1正常流程(均执行):

    2.2preHandle返回false:

 

四.相关配置及实现

  1.自定义拦截器类实现:

    1.1是否登录:

package com.swpu.o2o.interceptor.shopadmin;import java.io.PrintWriter;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;import com.swpu.o2o.entity.PersonInfo;/** * 管理系统拦截器 * @author ASUS * */public class ShopLoginInterceptor extends HandlerInterceptorAdapter{    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)            throws Exception {        //从session中取出用户信息        Object userObj=request.getSession().getAttribute("user");        if(userObj!=null){            //若用户信息不为空则将session里的用户信息转换成PersonInfos实体类对象            PersonInfo user=(PersonInfo)userObj;            if(user!=null&&user.getUserId()!=null&&user.getUserId()>0&&user.getEnableStatus()==1){                //若通过验证则返回true,拦截器返回true,控制层业务执行                return true;            }                    }        //若不满验证,则直接跳转到登录界面        PrintWriter out=response.getWriter();        out.println("");        out.println("");        out.println("");        return false;    }    }

 

    1.2是否有操作权限:

package com.swpu.o2o.interceptor.shopadmin;import java.util.List;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;import com.swpu.o2o.entity.Shop;public class ShopPermissionInterceptor extends HandlerInterceptorAdapter{    /**     * 在控制层执行业务前进行用户操作权限拦截     */    @Override    public boolean preHandle(HttpServletRequest request,            HttpServletResponse response, Object handler) throws Exception {        //从session获取当前选择的店铺        Shop currentShop = (Shop) request.getSession().getAttribute(                "currentShop");        @SuppressWarnings("unchecked")        //从session中获取当前用户可操作的d店铺列表        List
shopList = (List
) request.getSession().getAttribute( "shopList"); //非空判断 if (currentShop != null && shopList != null) { //遍历可操作的店铺列表 for (Shop shop : shopList) { //如果当前店铺在可操作的列表则返回true,进行接下来操作 if (shop.getShopId() == currentShop.getShopId()) { return true; } } } //不满足验证,返回false return false; }}

 

 

  2.配置文件:

 

转载于:https://www.cnblogs.com/lyq-biu/p/11017106.html

你可能感兴趣的文章
Part3_lesson2---ARM指令分类学习
查看>>
Django mysql 改用pymysql 驱动
查看>>
jQuery拖拽原理实例
查看>>
关于GrideView Item点击后出现错乱重叠的情况
查看>>
[Swift]LeetCode540. 有序数组中的单一元素 | Single Element in a Sorted Array
查看>>
[Swift]LeetCode409. 最长回文串 | Longest Palindrome
查看>>
.gitignore格式规范
查看>>
java集合(List集合与Map集合的数据转换)
查看>>
使用LoadRunner监控linux系统
查看>>
[RxJS] Reactive Programming - Using cached network data with RxJS -- withLatestFrom()
查看>>
MAC 环境下初始化mysql root 密码
查看>>
WordPress IndiaNIC FAQs Manager插件多个SQL注入漏洞
查看>>
Objective-C 内存管理
查看>>
SQL Server 中的6种事务隔离级别简单总结
查看>>
编程之美:队列中的最大最小值
查看>>
Q&A - 如何获取ip地址所在地
查看>>
蓝桥杯训练序列求和
查看>>
Flutter学习笔记(12)--列表组件
查看>>
问卷调查
查看>>
html5shiv.min.js
查看>>