springMVC拦截器

1.编写拦截器类,继承HandlerInterceptorAdapter类,重写preHandle(),afterCompletion()方法,并加入到Spring容器中

@Component
public class LoginInterceptor extends HandlerInterceptorAdapter {

    private static final ThreadLocal<UserInfo> THREAD_LOCAL = new ThreadLocal<>();

    @Autowired
    private JwtProperties jwtProperties;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 获取cookie信息
        String token = CookieUtils.getCookieValue(request, jwtProperties.getCookieName());
        String userKey = CookieUtils.getCookieValue(request, jwtProperties.getUserKeyName());

        // 如果都为空,设置userKey。
        if (StringUtils.isBlank(token) && StringUtils.isBlank(userKey)){
            userKey = UUID.randomUUID().toString();
            CookieUtils.setCookie(request, response, jwtProperties.getUserKeyName(), userKey, jwtProperties.getExpire());
        }

        // 不管有没有登录都要设置userKey
        UserInfo userInfo = new UserInfo();
        userInfo.setUserKey(userKey);

        // token不为空,解析token
        if (StringUtils.isNotBlank(token)){
            Map<String, Object> map = JwtUtils.getInfoFromToken(token, jwtProperties.getPublicKey());
            if (!CollectionUtils.isEmpty(map)) {
                userInfo.setId(new Long(map.get("id").toString()));
            }
        }

        // 保存到threadlocal
        THREAD_LOCAL.set(userInfo);

        // 如果token不为空,
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        THREAD_LOCAL.remove();
    }

    public static UserInfo getUserInfo(){
        return THREAD_LOCAL.get();
    }
}

注意:

  • 这里我们使用了ThreadLocal来存储查询到的用户信息,线程内共享,对外提供get方法,因此请求到达Controller后可以共享User
  • 并且对外提供了静态的方法:getUserInfo()来获取User信息
  • 在完成逻辑任务后,要进行释放,否则会内存泄漏

2.配置拦截器

@Configuration
public class MvcConfig implements WebMvcConfigurer {

    @Autowired
    private LoginInterceptor loginInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor).addPathPatterns("/**");
    }
}

热门文章

暂无图片
编程学习 ·

设计模式

设计模式 >**设计模式简介** 设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。…
暂无图片
编程学习 ·

超星尔雅《中庸》精读

超星学习通app《中庸》精读 答案 孟琢“四书”的形成(一)1【单选题】著作( )是一部论述了人生修养境界的道德哲学专著。 答案:《中庸》A、《周易》B、《史记》C、《诗经》D、《中庸》2【单选题】中国古代思想家( )是儒家学派的创始人,被后世尊称为万世师表。 答案:孔子A、孔…
暂无图片
编程学习 ·

如何用Nearby Service开发针对附近人群的精准广告推送功能

当你想找一家餐厅吃饭,却不知道去哪家,这时候手机跳出一条通知,为你自动推送附近优质餐厅的信息,你会点击查看吗?当你还在店内纠结于是否买下一双球鞋时,手机应用给了你发放了老顾客5折优惠券,这样的广告你有拒绝的理由吗?这样的广告不仅不会引起用户的厌烦,还满足了用…
暂无图片
编程学习 ·

Arduino项目实战——基于Arduino【智能垃圾桶】设计

Arduino项目实战——基于Arduino【智能垃圾桶】设计第一次接触Arduino是在大一的时候,距离现在已经五年,当时一个简单的“电子琴”项目就让我抓耳挠腮,根本不具备“面向百度编程”能力的我,用老师提供的文档跟我的组员用了好几天,才让Arduino跟蜂鸣器想起一首简单版的《小…
暂无图片
编程学习 ·

“百度大脑EasyDL经典版”拍了拍你,真实的产业应用get了吗?

在现有业务或方案的基础上,企业如何通过引入AI能力真正做到在降低成本的同时提升效率?质检流水线中,检测人员注意力与体力不支导致的低效、价格高昂的智能检测设备、千变万化的瑕疵形态都迫使企业投入更多成本;电网户外巡检中,越来越密集的电网分布、安全指标提升带来的巡…
暂无图片
编程学习 ·

13年蓝桥杯javaB组

13年蓝桥杯javaB组1.末世纪的星期天2.马虎的算式3.振兴中华4.黄金分数割5.有理数类6.三部排序7.错误票据 1.末世纪的星期天 曾有邪教称1999年12月31日是世界末日。当然该谣言已经不攻自破。 还有人称今后的某个世纪末的12月31日,如果是星期一则会是世界末日 有趣的是,任何一个…
暂无图片
编程学习 ·

[算法]最长公共前缀

题目编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 “”。示例输入: [“flower”,“flow”,“flight”] 输出: “fl”输入: [“dog”,“racecar”,“car”] 输出: “” 解释: 输入不存在公共前缀。这是一道简单题,没什么说的 class Solut…
暂无图片
编程学习 ·

CentOS系统安装好之后输入ifconfig指令无法查看ip解决办法

CentOS系统安装好之后输入ifconfig指令无法查看ip解决办法 第一次使用虚拟机安装CentOS系统,安装完之后想要通过Xshell连接Linux系统,在输入ifconfig指令后,无法查看到ip地址,也就无法通过ip地址连接Linux系统 本人经过多次百度,找了很多的解决办法都无法解决问题,但也发现了无…
暂无图片
编程学习 ·

记录一下开始搭建springboot+jsp项目遇到的一个问题

记录一下开始搭建springboot+jsp项目遇到的一个问题简述自己搭建项目的过程错误及解决总结加补充 最近刚开始学习搭建springboot项目,用到的ide工具是idea,前端用的是jsp 简述自己搭建项目的过程 直接上图在idea中创建一个springboot项目,选择好自己使用的jdk 刚创建好的项目…
暂无图片
编程学习 ·

2.4-1、斐波那契数列

1、斐波那切数列 【问题描述】 斐波那切数列0,1,1,2,3,5,8,13,21,34,55……从第三项起,每一项都是紧挨着的前两项的和。写出计算斐波那切数列的任意一个数据项递归程序。 【输入格式】 输入所求的项数。 【输出格式】 输出数据项的值。 【输入样例】fbi.in 10 【输出…
暂无图片
编程学习 ·

其实AQS并不难

不啰嗦,直接上干货 文章目录上锁解锁总结条件队列 newConditionCLH队列的数据结构扩展 interrupted 上锁ReentrantLock reentrantLock = new ReentrantLock(true);或者ReentrantLock reentrantLock = new ReentrantLock();看构造函数://无参的构造函数,默认为非公平锁public…
暂无图片
编程学习 ·

【浅拷贝】Object.create()、Object.assign()、扩展运算符

文章目录【ES5】Object.create() 方法【ES6】Object.assign() 方法【ES6】对象展开运算符 "..."【ES5】Object.create() 方法第一层嵌套层原对象未被修改,而第二层开始,原对象被影响(计数器例子只有一层)【ES6】Object.assign() 方法第一层嵌套层原对象未被修改,…
暂无图片
编程学习 ·

LeetCode 232. 用栈实现队列(C++)

** 232. 用栈实现队列 ** 题目描述: 使用栈实现队列的下列操作: push(x) -- 将一个元素放入队列的尾部。 pop() -- 从队列首部移除元素。 peek() -- 返回队列首部的元素。 empty() -- 返回队列是否为空。主要思路:入队时1.直接push到inStack中出队时1.如果outStack为空,先把…
暂无图片
编程学习 ·

6台路由器ospf+rip实验

一、环境OSPF路由协议是一种典型的链路状态(Link-state)的路由协议,一般用于同一个路由域内。在这里,路由域是指一个自治系统(Autonomous System),即AS,它是指一组通过统一的路由政策或路由协换路由信息的网络。在这个AS中,所有的OSPF路由器都维护一个相同的描述这个A…
暂无图片
编程学习 ·

葡萄酒分类

#加载数据 df = pd.read_csv("winequality-red.csv") df.head() #空值 df.isnull().any() df.describe()# 简单的数据统计 # 总酸度,把固定酸,挥发酸,柠檬酸三项合起来定义一个新的特征总酸量。 df[total acid] = df[fixed acidity] + df[volatile acidity] + df[…
暂无图片
编程学习 ·

jsoncpp的安装与配置

某些项目需要jsoncpp库,那么本文将介绍Ubuntu下安装jsoncpp库具体步骤。安装jsoncpp前必须安装scons。1.scons下载地址:https://sourceforge.net/projects/scons 可以选择对应的版本下载2.jsoncpp下载地址:http://sourceforge.net/projects/jsoncpp/files/3.解压scons-3.1.2…
暂无图片
编程学习 ·

简单动态字符串

SDS(simple synamic String)用作Redis默认字符串表示。C字符串只会作为字符串字面量用在一些无须对字符串进行修改的地方,例如打印日志等。 SDS定义 每个sds.h/sdshdr结构表示一个SDS值 struct sdshdr {//字符串的长度int len;// buf数组中未使用字节的数量int free;// 字节…
暂无图片
编程学习 ·

JAVA中集合的迭代/遍历方法iterator()

JAVA中集合的迭代/遍历方法以下讲解的遍历方式/迭代方式,是所有Collection通用的一种方式在Map集合中不能使用,在所有的Collection以及子类中使用第一步:创建迭代器对象: Iterator it = e.iterator();第二步:通过以上获取的迭代器对象开始迭代/遍历集合 以下两个方法为迭代…
暂无图片
编程学习 ·

Spring中MultipartHttpServletRequest实现文件上传

实现图片上传 用户必须能够上传图片,因此需要文件上传的功能。比较常见的文件上传组件有Commons FileUpload(http://jakarta.apache.org/commons/fileupload/a>)和COS FileUpload(http://www.servlets.com/cos),Spring已经完全集成了这两种组件,这里我们选择Commons …