SpringBoot过滤器与 * 使用方法深入分析
作者:一个双子座的Java攻城狮 发布时间:2023-08-18 10:20:03
什么是过滤器
过滤器 Filter 基于 Servlet 实现,过滤器的主要应用场景是对字符编码、跨域等问题进行过滤。Servlet 的工作原理是拦截配置好的客户端请求,然后对 Request 和 Response 进行处理。Filter 过滤器随着 web 应用的启动而启动,只初始化一次。
Filter 使用时需要继承 Filter 接口,实现对应的 init、doFilter 以及 destroy 方法即可。
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.springframework.stereotype.Component;
@Component
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("初始化 * ");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//做一些处理
System.out.println("doSomeThing");
chain.doFilter(request,response);
}
@Override
public void destroy() {
System.out.println("销毁 * ");
}
}
1、init:在容器启动时调用初始化方法,只会初始化一次
2、doFilter:每次请求都会调用 doFilter 方法,通过 FilterChain 调用后续的方法。
3、destroy:当容器销毁时,执行 destory 方法,只会被调用一次。
什么是 *
* 是 SpringMVC 中实现的一种基于 Java 反射( * )机制的方法增强工具, * 的实现是继承 HandlerInterceptor 接口,并实现接口的 preHandle、postHandle 和 afterCompletion 方法。
1、preHandle:请求方法前置拦截,该方法会在 Controller 处理之前进行调用,Spring 中可以有多个 Interceptor,这些 * 会按照设定的 Order 顺序调用,当有一个 * 在 preHandle 中返回 false 的时候,请求就会终止。
2、postHandle:preHandle 返回结果为 true 时,在 Controller 方法执行之后,视图渲染之前被调用
3、afterCompletion:在 preHandle 返回 ture,并且整个请求结束之后,执行该方法。
具体的代码实现如下,首先编写一个 * :
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Component
public class UserInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle");
String userName=request.getParameter("username");
String password = request.getParameter("password");
if (userName==null||password==null){
response.setStatus(500);
response.setContentType("text/html; charset=UTF-8");
response.getWriter().print("参数缺失");
return false;
}
//进行用户校验
if (userName.equals("admin")&&password.equals("admin")){
return true;
}else {
response.setStatus(500);
response.setContentType("text/html; charset=UTF-8");
response.getWriter().print("用户名或密码错误");
return false;
}
}
@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");
}
}
编写完 * 之后,通过一个配置类设置 * ,并且可以通过 addPathPatterns 和 excludePathPatterns 执行哪些请求需要被拦截,哪些不需要被拦截。
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 MvcConfig implements WebMvcConfigurer {
@Autowired
private UserInterceptor userInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(userInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/error");
}
}
再次访问 /test 页面,如果不带任何参数,就会在页面上提示 参数缺失。只有当带上参数 /test?username=admin&password=admin 才能够访问。
* 与过滤器的区别
相同点:
1、 * 与过滤器都是体现了 AOP 的思想,对方法实现增强,都可以拦截请求方法。
2、 * 和过滤器都可以通过 Order 注解设定执行顺序
不同点:
1、 过滤器属于 Servlet 级别, * 属于 Spring 级别。
Filter 是在 javax.servlet 包中定义的,要依赖于网络容器,因此只能在 web 项目中使用。
Interceptor 是 SpringMVC 中实现的,归根揭底 * 是一个 Spring 组件,由 Spring 容器进行管理。
2、过滤器和 * 的执行顺序不同:
下面通过一张图展示 Filter 和 Interceprtor 的执行顺序:
首先当一个请求进入 Servlet 之前,过滤器的 doFilter 方法进行过滤,进入 Servlet 容器之后,执行 Controller 方法之前, * 的 preHandle 方法进行拦截,执行 Controller 方法之后,视图渲染之前, * 的 postHandle 方法进行拦截,请求结束之后,执行 * 的 postHandle 方法。
3、 过滤器基于函数回调方式实现, * 基于 Java 反射( * )机制实现。
来源:https://blog.csdn.net/weixin_64061088/article/details/128432250
猜你喜欢
- 一个真实的故事大学的时候就开过一门课程,讲设计模式,可是大学生没什么编程实践经验,在大学里面听设计模式的感觉,就像听天书。听着都有道理,可是
- Java HashSetHashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合。HashSet 允许有 null 值。
- 一 :问题背景问题:当查询接口较复杂时候,数据的获取都需要[远程调用],必然需要花费更多的时间。 假如查询文章详情页面,需要如下标注的时间才
- 一、简介在上篇 ElasticSearch 文章中,我们详细的介绍了 ElasticSearch 的各种 api 使用。实际的项目开发过程中
- C++11 引入一个全新的线程库,包含启动和管理线程的工具,提供了同步(互斥、锁和原子变量)的方法,我将试图为你介绍这个全新的线
- 本文实例讲述了java实现的RSA加密算法。分享给大家供大家参考,具体如下:一、什么是非对称加密1、加密的密钥与加密的密钥不相同,这样的加密
- 配置步骤:1.导入Spring整合Junit的jar(坐标):<dependency> <gr
- 之前的两篇文章:Java实现两人五子棋游戏(二) 画出棋盘;Java实现两人五子棋游戏(三) 画出棋子;Java实现两人五子棋游戏(四) 落
- 一、HttpBasic模式的应用场景HttpBasic登录验证模式是Spring Security实现登录验证最简单的一种方式,也可以说是最
- 一、编译环境spring5.0.x源码gradle4.9jdk1.8_151IntelliJ IDEA 2020.1二、安装gradle1、
- 概述Spring boot 中的 @Conditional 注解是一个不太常用到的注解,但确实非常的有用,我们知道 Spring Boot
- 前言在淘宝内网里看到同事发了贴说了一个CPU被100%的线上故障,并且这个事发生了很多次,原因是在Java语言在并 * 况下使用HashMap
- 一. 概述在开发后端接口, 通常都会涉及检验参数必填校验, 一般我们的处理都是很粗暴的写个if()判断, 然后抛异常. 本文将介绍通过代理的
- 测试Spring Boot定时任务冲突时,使用的线程数量引入依赖:Spring Boot 2.6.1 <dependency>
- Oracle 数据库,查询增加RowBounds限制查询条数,默认是0到1000条private final static int rowL
- 最近在开发的过程当中,对于已有的代码,想将相关类绘制成UML类图,虽然现在有很多UML类图的优秀软件,比如ProcessOn(可视化编辑)、
- 在实际开发过程中,在线程池使用过程中可能会遇到各方面的故障,如线程池阻塞,无法提交新任务等。如果你想监控某一个线程池的执行状态,线程池执行类
- 这几天自己研究了关于地手机上面开发安卓地图的问题,发现百度官方示例demo讲解百度持续定位方面还是讲解的有些不清楚,本人研究了几次之后将其弄
- 优点1.观察者和被观察者是抽象耦合的。2.建立一套触发机制。缺点1.如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知
- maven依赖及一些配置这里主要是搭建项目常用到的maven依赖以及搭建项目会需要用到的一些配置文件,可能下面这些依赖还不是很全,但是应该会