当前位置: 首页 > news >正文

Servlet-Filter

文章目录

  • 一. Filter 过滤器
    • 1. 概括
    • 2. 原理
    • 3. api
      • 配置过滤器(Filter)拦截路径
        • 1.xml 方式
        • 2.注解方式
    • 4. 生命流程
      • a.执行流程
      • b.拦截路径
      • c.过滤器链
    • 5. 登录校验-Filter

一. Filter 过滤器

1. 概括

过滤器,顾名思义就是对事物进行过滤的,在 Web 中的过滤器,当然就是对请求进行过滤,我们使用过滤器,就可以对请求进行拦截,然后做相应的处理,实现许多特殊功能。如登录控制,权限管理,过滤敏感词汇等,是 JavaWeb 三大组件(Servlet、Filter、Listener)之一。

2. 原理

当我们使用过滤器时,过滤器会对浏览器的请求进行过滤,过滤器可以动态的分为 3 个部分,1.放行之前的代码,2.放行,3.放行后的代码,这 3 个部分分别会发挥不同作用。

  1. 第一部分代码会对浏览器请求进行第一次过滤,然后继续执行
  2. 第二部分代码就是将游览器请求放行,如果还有过滤器,那么就继续交给下一个过滤器
  3. 第三部分代码就是对返回的 Web 资源再次进行过滤处理
    我们使用过滤器,也就是说,不止请求会经过过滤器,我们的响应也会经过过滤器。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3. api

定义过滤器

//定义一个类,实现一个标准的Filter过滤器的接口
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);}@Override //销毁方法, 只调用一次public void destroy() {System.out.println("destroy 销毁方法执行了");}
}
  1. init 方法:过滤器的初始化方法。在 web 服务器启动的时候会自动的创建 Filter 过滤器对象,在创建过滤器对象的时候会自动调用 init 初始化方法,这个方法只会被调用一次。
  2. doFilter 方法:这个方法是在每一次拦截到请求之后都会被调用,所以这个方法是会被调用多次的,每拦截到一次请求就会调用一次 doFilter()方法。
  3. destroy 方法: 是销毁的方法。当我们关闭服务器的时候,它会自动的调用销毁方法 destroy,而这个销毁方法也只会被调用一次。

在过滤器 Filter 中,如果不执行放行操作,将无法访问后面的资源。 放行操作:chain.doFilter(request, response);

在定义完 Filter 之后,Filter 其实并不会生效,还需要完成 Filter 的配置,Filter 的配置非常简单,只需要在Filter类上添加一个注解:@WebFilter,并指定属性urlPatterns,通过这个属性指定过滤器要拦截哪些请求。

@WebFilter(urlPatterns = "/*") //配置过滤器要拦截的请求路径( /* 表示拦截浏览器的所有请求 )

当我们在 Filter 类上面加了@WebFilter 注解之后,接下来我们还需要在启动类上面加上一个注解@ServletComponentScan,通过这个@ServletComponentScan 注解来开启 SpringBoot 项目对于 Servlet 组件的支持。

过滤器并不会管资源是否存在,而只会对配置的拦截路径进行拦截。拦截不仅会对请求进行拦截,而且还会对响应进行拦截。

配置过滤器(Filter)拦截路径

1.xml 方式

xml 方式可以说是和 Servlet 使用 xml 配置方式一样了。

    <filter><filter-name>myFilter</filter-name><!-- <筛选器名称>myFilter</筛选器名称> --><filter-class>com.clucky.filter.MyFilter</filter-class></filter><filter-mapping><filter-name>myFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>

这个就是 xml 配置方式,只不过把注解换成了 xml 标签来配置,里面属性都是一样的,这个和 Servlet 的配置方式基本一样,这里就不再赘述了。

2.注解方式

使用@WebFilter,里面的多个参数用,进行分隔。

参数说明
filterName该 filter 的名字
initParams初始化参数
displayNamefilter 显示名称
servletNames指定对哪些 servlet 进行过滤
asyncSupported是否支持异步模式
urlPatterns指定拦截路径
value指定拦截路径

**注意:**urlPatterns 和 value 是一样的。urlPatterns 和 value 只能配置一个,不能两个都配置,两个都配置就会报错。

4. 生命流程

a.执行流程

Filter 的执行流程主要包括初始化请求处理响应处理销毁这四个阶段。放行操作,放行就是调用 FilterChain 对象当中的 doFilter()方法,在调用 doFilter()这个方法之前所编写的代码属于放行之前的逻辑。在放行后访问完 web 资源之后还会回到过滤器当中,回到过滤器之后如有需求还可以执行放行之后的逻辑,放行之后的逻辑我们写在 doFilter()这行代码之后。

b.拦截路径

拦截路径urlPatterns 值含义
拦截具体路径/login只有访问/login 路径是,才会被拦截
目录拦截/emps/*访问/emps 下的所有资源,都会被拦截
拦截所有/*访问所有资源,都会被拦截

c.过滤器链

所谓过滤器链指的是在一个 web 应用程序当中,可以配置多个过滤器,多个过滤器就形成了一个过滤器链。以注解方式配置的 Filter 过滤器,它的执行优先级是按时过滤器类名的自动排序确定的,类名排名越靠前,优先级越高

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

它用于将请求传递给过滤器链中的下一个过滤器或目标资源(如 Servlet)。在 Filter 的实现类中,通常会重写doFilter方法来处理请求和响应。当一个过滤器完成其处理后,它会调用doFilter方法,并将控制权传递给下一个过滤器。如果没有其他过滤器需要处理该请求,那么控制权将传递给目标资源。

5. 登录校验-Filter

登录校验过滤器:LoginCheckFilter

@Slf4j
@WebFilter(urlPatterns = "/*") //拦截所有请求
public class LoginCheckFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {//前置:强制转换为http协议的请求对象、响应对象 (转换原因:要使用子类中特有方法)HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;//1.获取请求urlString url = request.getRequestURL().toString();log.info("请求路径:{}", url); //请求路径:http://localhost:8080/login//2.判断请求url中是否包含login,如果包含,说明是登录操作,放行if(url.contains("/login")){chain.doFilter(request, response);//放行请求return;//结束当前方法的执行}//3.获取请求头中的令牌(token)String token = request.getHeader("token");log.info("从请求头中获取的令牌:{}",token);//4.判断令牌是否存在,如果不存在,返回错误结果(未登录)if(!StringUtils.hasLength(token)){log.info("Token不存在");Result responseResult = Result.error("NOT_LOGIN");//把Result对象转换为JSON格式字符串 (fastjson是阿里巴巴提供的用于实现对象和json的转换工具类)String json = JSONObject.toJSONString(responseResult);response.setContentType("application/json;charset=utf-8");//响应response.getWriter().write(json);return;}//5.解析token,如果解析失败,返回错误结果(未登录)try {JwtUtils.parseJWT(token);}catch (Exception e){log.info("令牌解析失败!");Result responseResult = Result.error("NOT_LOGIN");//把Result对象转换为JSON格式字符串 (fastjson是阿里巴巴提供的用于实现对象和json的转换工具类)String json = JSONObject.toJSONString(responseResult);response.setContentType("application/json;charset=utf-8");//响应response.getWriter().write(json);return;}//6.放行chain.doFilter(request, response);}
}

http://www.mrgr.cn/news/68730.html

相关文章:

  • 跨域及解决跨域
  • Vue(JavaScript)读取csv表格并求某一列之和(大浮点数处理: decimal.js)
  • ctfshow web入门黑盒测试web380-384
  • ORACLE 19C 安装数据库补丁的详细过程
  • Docker Compose部署Rabbitmq(Dockerfile安装延迟队列)
  • 每日OJ题_牛客_DP59数位染色_01背包_C++_Java
  • Linux 常用操作指令大揭秘(上)
  • PaddleOCR安装教程
  • 一文读懂肖特基二极管
  • C#语言:现代软件开发的核心工具
  • 数据结构_哈夫曼树及其应用
  • 智慧矿山建设方案
  • Github的OAuth2登录
  • 块存储、文件存储和对象存储详细介绍
  • 自制头文件:BetterPrint(更好的输出)
  • 首批入驻 | ZStack AIOS平台智塔入驻信通院“铸基计划”应用商店
  • 【Qt】Macbook M1下载安装
  • Python 虚拟环境创建
  • 用户登录密码存储加密策略(附Python 和 bcrypt 库进行安全密码验证)
  • 人工智能——小白学习指南
  • 第10章 多表查询
  • shell脚本练习
  • vue3 + vite 实现版本更新检查(检测到版本更新时提醒用户刷新页面)
  • 设计模式-七个基本原则之一-接口隔离原则 + SpringBoot案例
  • 文件IO拷贝应用
  • c++模板的优点和缺点