通过实现HandlerInterceptor接口实现一个拦截器

2023-09-22 15:09:07

1. 简介

web应用开发中,拦截器的应用场景非常广泛,主要用于:

  1. 登陆验证:提取request中请求头携带的token信息;
  2. 鉴权:判断该用户是否有权限访问某个资源
  3. 日志记录:记录该handler的入 和 出
  4. 性能监控、通用行为等等一些其它的操作。

2. spring中使用拦截器的方式

spring为我们提供了一个接口:HandlerInterceptor,该接口提供了三个方法:

default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
}

default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}

default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}

通过名字不难理解每个方法其中的意思:
preHandler() 方法是调用我们程序中写的controller之前执行的;
postHander() 方法是controller执行完毕之后,spring会调用该框架;
afterCompletion() 方法是视图渲染完毕之后被执行。

preHander()方法返回true时,表示可以进入咱们开发的handler中,否则不能进入。例如,在preHander中进行鉴权案例:

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    String authHeader = AuthHeaderUtils.getBearerToken();
    String tenantId = AuthHeaderUtils.getTenantId();
    String userId = AuthHeaderUtils.getUserId();

    // 未携带token
    if (StringUtils.isBlank(authHeader)) {
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, UNAUTHORIZED);
        return false;
    }
    AuthService authService = SpringUtil.getBean(AuthService.class);
    // 校验token
    TokenInfoDTO tokenInfoDTO = authService.checkToken(authHeader);
    if (Objects.isNull(tokenInfoDTO)) {
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, UNAUTHORIZED);
        return false;
    }
    // 是否需要刷新token
    if (tokenInfoDTO.getRefresh()) {
        authHeader = authService.refreshToken(tenantId, userId);
    }
    // 获取用户
    UserDTO user = authService.getUser(authHeader);
    if (Objects.isNull(user)) {
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, UNAUTHORIZED);
        return false;
    }
    // 将用户信息set到threadLocal中。
    VBPAppContext.setUserObj(user);
    
    response.setHeader(HEADER_AUTHORIZATION, authHeader);
    return HandlerInterceptor.super.preHandle(request, response, handler);
}

上述代码中通过鉴权的用户将会被set到threadLocal中,虽然ThreadLocal中通过实现WeakReference接口进行弱引用防止内存泄漏,但是未被有效释放的对象仍然会占用内存,因此在一整个请求结束之后,最好及时remove一下,即:在拦截器的afterCompletion()方法中及时调用remove:

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
        throws Exception {
    VBPAppContext.removeUserObj();
}
更多推荐

我的创作纪念日

机缘不知不觉已经过去蛮久了,为何我会到csdn中来写博客呢?最开始我只是想对于我这样的应届生如果有一个自己的博客网站对于找工作会是一个加分的项。写了20篇之后呢我就觉得我的目的不是那么功利了,因为我在学习的过程中遇到了太多的困难,都是通过别人的分享去获得解决的办法的,从别人那里去获取我便也想给别人出一份力,对于没有导师

vue前端 router路由hash和history模式区别

vue-router路由有两种方式,hash模式和history模式,接下来浅谈一下两者区别模式通俗解释兼容原理hashurl尾巴后的#号及后面的字符都是hash模式兼容IE8及以上于hash值变化不会导致浏览器向服务器发出请求,而且hash改变会触发hashchange事件(hashchange只能改变#后面的url

改写paddledetection为cmake版(c++)

下载源代码官方地址:https://gitee.com/paddlepaddle/PaddleDetection网盘:paddledetection链接:https://pan.baidu.com/s/1g0z5SYQNDR1pwe9iAtvR3A?pwd=ktl6提取码:ktl6paddleocr链接:https:/

腾讯云OCR - 降低客服财务运营成本

说明:参与中秋活动一、前言:随着图片时代的飞速发展,大量的文字内容为了优化排版和表现效果,都采用了图片的形式发布和存储,这为内容的传播和安全性带来了很大的便利,需要做重复性劳动。OCR文字扫描工具也逐渐的应运而生,主要是为了帮助用户解决了内容编辑的难题。二、OCR是什么?OCR全称是OpticalCharacterRe

ELK 企业级日志分析系统 ELFK

目录一、概述二、组件介绍2.1、ElasticSearch2.2、Kiabana2.3、Logstash2.4、可以添加的其它组件:Filebeat2.5、缓存/消息队列(redis、kafka、RabbitMQ等)2.6、Fluentd三、ELK工作原理四、实例演示1.ELK之部署"E"Elasticsearch2.

视频号视频怎么下载(视频号如何下载里面的视频)

根据大家分享出来的视频号如何下载里面的视频的相关提供的下载方案,我们特别总结了多款可以下载视频号视频怎么下载的办法!如果你还不会提取视频号里的视频,赶快来看看视频号里的视频怎么保存到相册的吧!1:视频下载缓存该方法仅针对安卓手机,具体操作方式打开手机的文件管理,找到手机的本地储存空间;在文件中依次找到Android—d

软件测试技术之地图导航的测试用例

外观测试屏幕显示不能有花屏、黑点和闪屏,清晰度、亮度、颜色要正常。检测所有按键都能起到相应作用,是否手感不良。UI显示状态、颜色、清晰度、效果。控制:放大,缩小,音量调节功能测试。交叉路口查询测试,点击交叉路口查询后能正确输入城市名称吗。关键字查询:点击关键字查询后搜索道路能正确的输入城市名称和关键字进行道路查询吗。6

Linux网络编程

一.协议1.1什么是协议从应用的角度出发,协议可理解为“规则”,是数据传输和数据的解释的规则。假设,A、B双方欲传输文件。规定:第一次,传输文件名,接收方接收到文件名,应答OK给传输方;第二次,发送文件的尺寸,接收方接牧到该数据再次应答一个OK;第三次.传输文件内容。同样.接收方接收数据完成后应答OK表示文件内容接收成

PostgreSQL 数据库实现公网远程连接

文章目录前言1.安装postgreSQL2.本地连接postgreSQL3.Windows安装cpolar4.配置postgreSQL公网地址5.公网postgreSQL访问6.固定连接公网地址7.postgreSQL固定地址连接测试前言PostgreSQL是一个功能非常强大的关系型数据库管理系统(RDBMS),下面简

在pandas中使matplotlib动态画子图的两种方法【推荐gridspec】

先上对比图,第一种方法,这里仅展示1个大区,多个的话需要加一层循环就可以了,主要是看子图的画法当大区下面的国家为1个或2个时,会进行报错#获取非洲国家列表african_countries=df[df['大区']=='南亚大区']['进口国'].unique()#动态计算子图的行列数量num_countries=len

datax同步数据翻倍,.hive-staging 导致的问题分析

一、背景有同事反馈Datax从Hive表同步数据到Mysql数据翻倍了。通过查看Datax任务日志发现,翻倍的原因是多读取了.hive-staging_xx开头的文件。接下里就是有关.hive-staging的分析。二、环境Hive版本2.1.1三、分析3.1.hive-staging_hive产生的原因通过Spark

热文推荐