SpringBoot中Filter和Interceptor快速入门

2023-09-20 20:32:37

一、Filter

1.定义

说明:filter文件里面DemoFilter类实现Filter接口。

package com.itheima.filter;


import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
//用于指定一个过滤器要拦截的URL模式。
@WebFilter(urlPatterns = "/*")
public class DemoFilter implements Filter {
    @Override //初始化方法, 只调用一次
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("init 初始化方法执行了");
    }

    @Override //拦截到请求之后调用, 调用多次
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("Demo 拦截到了请求...放行前逻辑");
        //放行
        chain.doFilter(request, response);

        System.out.println("Demo 拦截到了请求...放行后逻辑");
    }

    @Override //销毁方法, 只调用一次
    public void destroy() {
        System.out.println("destroy 销毁方法执行了");
    }
}

2.测试类

package com.itheima;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
//开启了servlet组件支持(拦截支持)
@ServletComponentScan
@SpringBootApplication
public class TliasWebManagementApplication {

    public static void main(String[] args) {
        SpringApplication.run(TliasWebManagementApplication.class, args);
    }

}

 3.过滤器链

说明:请求->放行前逻辑->放行->资源->放行;创建一个另一个XbcFilter类实现Filter接口。执行顺序根据类名字母顺序一次进行。

package com.itheima.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
//执行顺序类名首字母靠前就在前
@WebFilter(urlPatterns = "/*")
public class XbcFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("Abc 拦截到了请求...放行前逻辑");
        //放行
        chain.doFilter(request,response);

        System.out.println("Abc 拦截到了请求...放行后逻辑");
    }
}

4.完成的filter类

package com.itheima.filter;

import com.alibaba.fastjson.JSONObject;
import com.itheima.controller.utils.JwtUtils;
import com.itheima.pojo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Slf4j
@WebFilter(urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//       强转我们可以使用HttpServletRequest和ServletResponse对象中的所有方法,而不受Spring框架的限制。
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        //1.获取请求url。
        String url = req.getRequestURL().toString();
        log.info("请求的url: {}", url);

        //2.判断请求url中是否包含login,如果包含,说明是登录操作,放行。
        if (url.contains("login")) {
            log.info("登录操作, 放行...");
            chain.doFilter(request, response);
//            如果不写return语句,那么程序会继续执行下一个过滤器,直到过滤器链中的最后一个过滤器执行完毕。
            return;
        }

        //3.获取请求头中的令牌(token)。
        String jwt = req.getHeader("token");

        //4.判断令牌是否存在,如果不存在,返回错误结果(未登录)。
        if (!StringUtils.hasLength(jwt)) {
            log.info("请求头token为空,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 对象--json --------> 阿里巴巴fastJSON
            String notLogin = JSONObject.toJSONString(error);
//            HttpServletResponse接口提供了一个getWriter()方法,该方法返回一个PrintWriter对象,用于将数据写入HTTP响应中。
            resp.getWriter().write(notLogin);
            return;
        }

        //5.解析token,如果解析失败,返回错误结果(未登录)。
        try {
//            ctrl+alt+t   try,catch使用
            JwtUtils.parseJWT(jwt);
        } catch (Exception e) {//jwt解析失败
            e.printStackTrace();
            log.info("解析令牌失败, 返回未登录错误信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 对象--json --------> 阿里巴巴fastJSON
//            将error对象转成字符串
            String notLogin = JSONObject.toJSONString(error);
//            直接响应给浏览器
            resp.getWriter().write(notLogin);
            return;
        }

        //6.放行。
        log.info("令牌合法, 放行");
        chain.doFilter(request, response);

    }
}

 

二、Interceptor

1.概念

说明:是一种动态拦截方法调用的机制,类似于过滤器。Spig框架中提供的,用来动态拦截控制器方法的执行。

2.定义拦截器类

package com.itheima.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.itheima.controller.utils.JwtUtils;
import com.itheima.pojo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
//IOC容器管理
@Component
public class LoginCheckInterceptor implements HandlerInterceptor {
    @Override //目标资源方法运行前运行, 返回true: 放行, 放回false, 不放行
    public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {
        //1.获取请求url。
        String url = req.getRequestURL().toString();
        log.info("请求的url: {}",url);

        //2.判断请求url中是否包含login,如果包含,说明是登录操作,放行。
        if(url.contains("login")){
            log.info("登录操作, 放行...");
            return true;
        }

        //3.获取请求头中的令牌(token)。
        String jwt = req.getHeader("token");

        //4.判断令牌是否存在,如果不存在,返回错误结果(未登录)。
        if(!StringUtils.hasLength(jwt)){
            log.info("请求头token为空,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 对象--json --------> 阿里巴巴fastJSON
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return false;
        }

        //5.解析token,如果解析失败,返回错误结果(未登录)。
        try {
            JwtUtils.parseJWT(jwt);
        } catch (Exception e) {//jwt解析失败
            e.printStackTrace();
            log.info("解析令牌失败, 返回未登录错误信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 对象--json --------> 阿里巴巴fastJSON
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return false;
        }

        //6.放行。
        log.info("令牌合法, 放行");
        return true;
    }

    @Override //目标资源方法运行后运行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle ...");
    }

    @Override //视图渲染完毕后运行, 最后运行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion...");
    }
}

3. 配置类

package com.itheima.config;

import com.itheima.interceptor.LoginCheckInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration //配置类
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private LoginCheckInterceptor loginCheckInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
//        registry添加一个拦截器,定义的一个loginCheckInterceptor类;拦截什么路径的资源 /**表示所有容器,/*表示一级路径,不拦截/login资源
        registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**").excludePathPatterns("/login");
    }
}

三、总结

  1. Filter是Servlet API中的一种组件,它可以在HTTP请求到达Servlet之前或之后对请求进行处理。Filter可以实现一些常见的功能,例如身份验证、授权、数据压缩、缓存等。Filter通常是单例的,并且可以在整个应用程序中共享。
  2. Interceptor是Spring MVC框架中的一种组件,它可以在Controller方法执行之前或之后对请求进行处理。Interceptor可以实现一些常见的功能,例如请求参数验证、日志记录、统计请求次数等。Interceptor通常是基于注解的,可以在Controller方法上使用注解来标识需要拦截的方法。

 

更多推荐

记一次 .NET 某餐饮小程序 内存暴涨分析

一:背景1.讲故事前些天有位朋友找到我,说他的程序内存异常高,用vs诊断工具加载时间又太久,让我帮忙看一下到底咋回事,截图如下:确实,如果dump文件超过10G之后,市面上那些可视化工具分析起来会让你崩溃的,除了时间久之外这些工具大多也不是用懒加载的方式,比如dotmemory会把数据全部灌入内存,针对这种dump,你

滚雪球学Java(29):数组长度和排序算法:让你的程序更高效

🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎大家关注&&收藏!持续更新中,up!up!up!!前言在上一篇文章中,我们学习了数组的常用技巧和方法。本篇文章将深入探讨数组长度以及如何使用排序算法提高程序效率。摘要数组长度是数组中元素的个数,可以使用length属性获取。

Vue入门

Vue的介绍1.什么是vue?vue是一个渐进式js框架,它被设计用于构建用户界面和单页应用程序。Vue.js很容易上手,易于学习,并且是一种非常灵活的开发工具。1特点:轻量级:Vue.js的文件大小只有20KB左右,非常适合快速构建小型应用程序。双向数据绑定:Vue.js使用MVVM(Model-View-ViewM

【MATLAB第75期】#源码分享 | 基于MATLAB的不规则数据插值实现时间序列数据扩充

【MATLAB第75期】#源码分享|基于MATLAB的不规则数据插值实现时间序列数据扩充如时间数据以单位1为间隔排序,可插间隔为0.5的数据。一、实现效果1.规则间隔数据2.非规则间隔数据二、主程序代码1.插值测试效果%%清空环境变量warningoff%关闭报警信息closeall%关闭开启的图窗clear%清空变量

MySQL(3)索引实践一

一、索引下推:对于辅助的联合索引(name,age),正常情况按照最左前缀原则,SELECT*FROMuserWHEREnamelike'xiao%'ANDage=22这种情况只会走name字段索引,因为根据name字段过滤完,得到的索引行里的age是无序的,无法很好的利用索引。在MySQL5.6之前的版本,这个查询只

Matlab之并行程序设计实战教程

在本教程中,我们将介绍如何使用Matlab进行并行程序设计。我们将通过一个简单的示例来演示如何将串行代码转换为并行代码,以提高程序的执行效率。示例:计算一个数组的平方和假设我们有一个包含10000个元素的数组,我们想计算该数组的平方和。首先,我们来看看如何使用串行代码实现这个任务。%%串行代码array=1:10000

javase javaee javame

1.JavaSEJavaSE(JavaPlatform,StandardEdition):Java平台标准版。它是JavaEE和JavaME的基础,之前称为J2SE,用来开发C/S架构软件,通俗来讲,就是开发电脑桌面的应用软件、电脑上运行的软件,例如,Java应用程序开发平台Eclipse。同时也是Java的基础,Ja

阿里云服务器租用费用价格表(2023新版报价)

租用阿里云服务器怎么收费?阿里云服务器配置不同一年价格也不同,阿里云2核2G3M带宽108元一年、2核4G4M带宽297.98元12个月,云服务器u1公网带宽可选1M到5M,系统盘为ESSD云盘40GB起,CPU内存配置可选2核2G、2核4G、4核8G、8核16G等配置,还有ECS计算型c7、通用型g7和内存型r7多C

Python子进程管理与进程信息获取

1.Python子进程模块subprocesssubprocess模块允许我们启动一个新进程,并连接到它们的输入/输出/错误管道,从而获取返回值。(1)run方法首先我们来看看run方法的使用,该方法的参数如下:args:表示要执行的命令。必须是一个字符串或字符串参数列表。stdin、stdout和stderr:子进程

【UE 粒子练习】05——创建光束类型粒子

效果步骤1.新建一个材质,这里命名为“Mat_Beam”设置材质域为表面,混合模式为半透明,着色模型为无光照材质节点如下:2.新建一个粒子系统,命名为“P_Beam”打开“P_Beam”,在发射器中新建一个光束数据在必需模块中将材质改为上一步创建的材质“Mat_Beam”在“光束数据”模块中,设置光束方法为“目标”,这

【Graph Net学习】DeepWalk/Node2Vec实现Graph Embedding

一、简介本文主要通过代码实战介绍基础的两种图嵌入方式DeepWalk、Node2Vec。DeepWalk(KDD2014):首个影响至今的图的Embedding算法,DeepWalk算法是一种用于学习节点表示的方法,常用于网络图中的节点的嵌入表示。模型目标输入输出Word2VecWordSentenceWordEmbe

热文推荐