JAVA中的拦截器、过滤器

article/2025/10/20 11:18:35

JAVA变成拦截器、过滤器

  • 一、拦截器
    • 1、简介说明
    • 2、源码及方法说明
    • 3、拦截器自定义应用
  • 二、过滤器
    • 1、简介说明
    • 2、源码及方法说明
    • 3、过滤器的自定义应用
  • 三、Springboot中的WebMvcConfigurer
    • 1、简介
    • 2、主要方法
    • 3、添加拦截器
  • 四、区别
    • 1、原理
    • 2、触发
    • 3、其他

一、拦截器

1、简介说明

相关解释:拦截器依赖于页面有访问controller的操作,且属于SpringMVC体系的动态拦截调用机制,是java中AOP思想的运用。
来看看源码作者的注释:
在这里插入图片描述
其中倒数第二段话,描述其类似于过滤器,但其特点只允许使用自定义预处理,不能处理程序本身。此处可体现AOP思想。
过滤器是在web.xml中配置,web.xml是应用程序上下文中的HandlerInterceptor。

最后一段话,则体现了拦截器常用情况,如常见处理程序代码和授权检查。
而过滤器非常适合请求内容和视图内容处理,如多部分表单和GZIP压缩。

2、源码及方法说明

HandlerInterceptor
在这里插入图片描述

HandlerInterceptor接口中有3个方法:
preHandler():该方法会在控制器方法前执行,其返回值表示是否中断后续操作。当其返回值为true时,表示继续向下执行;当其返回值为false时,会中断后续的所有操作。
postHandle():该方法会在控制器方法调用之后,且解析视图之前执行。可以通过此方法对请求域中的模型和视图做出进一步的修改。
afterCompletion():该方法会在整个请求完成,即视图渲染结束之后执行。可以通过此方法实现一些资源清理、记录日志信息等工作。

3、拦截器自定义应用

实现 org.springframework.web.servlet.HandlerInterceptor 接口
如常见的白名单控制

package com.framework;import com.alibaba.fastjson.JSON;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@Component
public class WhiteRosterInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {if(checkWhiteList()){return true;}response.setContentType("application/json; charset=utf-8");response.setCharacterEncoding("UTF-8");response.getWriter().append(JSON.toJSONString("白名单暂未设置"));return false;}private Boolean checkWhiteList(){//业务处理return true;}}

二、过滤器

1、简介说明

相关解释:java过滤器能够对目标资源的请求和响应进行截取。
来看看源码作者的注释:
在这里插入图片描述
其描述中说明该过滤器为基于(a servlet or static content)。
同时也将其现有应用场景进行了说明,如权限过滤,加密过滤,图像转换过滤等等。

2、源码及方法说明

Filter
在这里插入图片描述
Filter接口中有3个方法:
init():初始化参数,在创建Filter时自动调用,如需要设置初始化参数,可写到该方法中。
doFilter():拦截到要执行的请求时,doFilter就会执行。写对请求和响应的预处理。
destroy():销毁时Filter自动调用。
init()和destroy(),为default方法,可不实现,但doFilter()必须实现,且方法中传进来的FilterChain对象用来调用下一个过滤器。

3、过滤器的自定义应用

实现javax.servlet.Filter 接口
如常见的加解密过滤器

package com.framework;import com.AesUtil;
import com.response.ResponseWrapper;
import org.springframework.stereotype.Component;
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 javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;@Component
public class EncryptFilter implements Filter{@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {if(isExcept(request)){chain.doFilter(request, response);return;}response.setContentType("application/json; charset=utf-8");response.setCharacterEncoding("UTF-8");ResponseWrapper responseWrapper = new ResponseWrapper((HttpServletResponse) response);chain.doFilter(request, responseWrapper);byte[] resData = responseWrapper.getResponseData();String encrypt = AesUtil.encrypt(new String(resData, "utf-8"), "AesKey");PrintWriter out = response.getWriter();out.print(encrypt.replaceAll("[\\s*\t\n\r]", ""));out.flush();out.close();}private Boolean isExcept(ServletRequest HttpRequest){//业务处理,是否不加密return true;}@Overridepublic void destroy() {}
}

依赖的 ResponseWrapper.java

package com.response;import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;public class ResponseWrapper extends HttpServletResponseWrapper {private ByteArrayOutputStream byteArrayOutputStream = null;private ServletOutputStream servletOutputStream = null;private PrintWriter printWriter = null;public ResponseWrapper(HttpServletResponse response) throws IOException {super(response);byteArrayOutputStream = new ByteArrayOutputStream();servletOutputStream = new WrapperOutputStream(byteArrayOutputStream);printWriter = new PrintWriter(new OutputStreamWriter(byteArrayOutputStream,this.getCharacterEncoding()));}private class WrapperOutputStream extends ServletOutputStream {private ByteArrayOutputStream bos = null;public WrapperOutputStream(ByteArrayOutputStream stream) throws IOException {bos = stream;}@Overridepublic void write(int b) throws IOException {bos.write(b);}@Overridepublic void write(byte[] b) throws IOException {bos.write(b, 0, b.length);}@Overridepublic boolean isReady() {return false;}@Overridepublic void setWriteListener(WriteListener writeListener) {}}}

当需要使用多个过滤器时,需要设置过滤器先后顺序。
即在EncryptFilter类中使用 @Order() 注解,数值越小,优先级越高,执行顺序越靠前。

加密相关链接:
Springboot项目报文加密(采用AES、RSA动态加密策略):
https://blog.csdn.net/qq_38254635/article/details/129275971
Springboot集成AES加密:
https://blog.csdn.net/qq_38254635/article/details/129622075

三、Springboot中的WebMvcConfigurer

1、简介

为Spring内部的配置方式,通过JavaBean的方式来替代传统的xml配置文件形式,可自定义一些Handler,Interceptor,ViewResolver,MessageConverter,需创建配置类并实现WebMvcConfigurer接口

2、主要方法

addViewControllers:将一个请求转到一个页面。
addResourceHandlers:静态资源的地址映射。
configureMessageConverters:将@ResponseBody实体转FastJson字符串返回,可以返回实体进行重写。
addCorsMappings:实现ajax跨域请求。
addInterceptors:添加拦截器。

3、添加拦截器

1、自定义一个注解,用作手动单个接口忽略拦截

package com.annotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface IgnoreInterceptor {
}

2、自定义配置,用作某路径下的请求批量忽略拦截
放置在yml配置文件中。
SpringBoot加载自定义yml中的配置参数:https://blog.csdn.net/qq_38254635/article/details/112033193

3、编写拦截器类 WebMvcConfig.java

package com.config;import com.alibaba.fastjson.JSON;
import com.annotation.IgnoreInterceptor;
import com.framework.WhiteRosterInterceptor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Value("#{'${spring.excludePath}'.split(',')}")private List<String> excludePath;@Resourceprivate WhiteRosterInterceptor whiteRosterInterceptor;@Overridepublic void addViewControllers(ViewControllerRegistry registry) {registry.addViewController("/").setViewName("index");}@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");}@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new HandlerInterceptor() {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {if (handler instanceof HandlerMethod) {HandlerMethod method = (HandlerMethod) handler;IgnoreInterceptor methodAnnotation = method.getMethodAnnotation(IgnoreInterceptor.class);if(null != methodAnnotation) return true;if (!isLogin(request)) {response.setContentType("application/json; charset=utf-8");response.setCharacterEncoding("UTF-8");response.getWriter().append(JSON.toJSONString("未登录"));return false;}refreshLogin(request);return true;}return true;}private Boolean isLogin(HttpServletRequest request) {//判断用户是否登录return true;}private void refreshLogin(HttpServletRequest request) {//刷新登录信息}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {//处理完业务后,清除用户的登录相关信息,永远放在最后处理}}).addPathPatterns("/**").excludePathPatterns(excludePath);registry.addInterceptor(whiteRosterInterceptor).addPathPatterns("/api/**");}}

4、说明
拦截器方式addInterceptors中,可实现多个拦截器。
可通过 registry.addInterceptor()增加拦截器,如上接口,增加了文中白名单拦截器。
addPathPatterns:拦截路径,**表示匹配后续所有路径
excludePathPatterns:忽略路径,接口中excludePath使用yml配置的路径,进行忽略操作。
IgnoreInterceptor:自定义注解,手动忽略某请求,在拦截器做了单独处理。
如自定义拦截器,可通过注入的方式添加。
执行顺序也根据配置的顺序,依次执行。

四、区别

1、原理

拦截器方法都是通过代理的方式来调用的,是基于反射机制实现的,依赖于web框架。
过滤器的实现是基于回调函数的。依赖于Servlet容器。

2、触发

如1.1中源码注释所说。
拦截器:对请求在handler【Controller】前后进行处理,属于应用上下文。
过滤器:对请求在进入后Servlet之前或之后进行处理,允许交换请求和响应对象,使用web.xml配置。
在这里插入图片描述
拦截器和过滤器执行顺序:
1、Filter.init();
2、Filter.doFilter(); before doFilter
3、HandlerInterceptor.preHandle();
4、Controller方法执行
5、HandlerInterceptor.postHandle();
6、DispatcherServlet视图渲染
7、HandlerInterceptor.afterCompletion();
8、Filter.doFilter(); after doFilter
9、Filter.destroy();

在这里插入图片描述

3、其他

过滤器:每一次都传入FilterChain对象,达到最后接口回调的效果。
拦截器:任何一个拦截器的preHandle为false,则其后的所有拦截器都不会执行。只有所有的拦截器preHandler都为true,postHandle才会执行。

多个过滤器设置执行顺序:增加 @Order() 注解,数值越小,优先级越高,执行顺序越靠前。
在这里插入图片描述
多个拦截器设置执行顺序:可通过实现Ordered接口来实现。
在这里插入图片描述

参考链接:
https://baijiahao.baidu.com/s?id=1677716748772601748
https://blog.csdn.net/m0_53123540/article/details/124924596
https://blog.csdn.net/king101125s/article/details/104372380


http://chatgpt.dhexx.cn/article/mhobaJvU.shtml

相关文章

Java开发学习----拦截器(Interceptor)详细解析

一、拦截器概念 讲解拦截器的概念之前&#xff0c;我们先看一张图: (1)浏览器发送一个请求会先到Tomcat的web服务器 (2)Tomcat服务器接收到请求以后&#xff0c;会去判断请求的是静态资源还是动态资源 (3)如果是静态资源&#xff0c;会直接到Tomcat的项目部署目录下去直接访…

JAVA三大器之拦截器

1&#xff0c;拦截器的概念 java里的拦截器是动态拦截Action调用的对象&#xff0c;它提供了一种机制可以使开发者在一个Action执行的前后执行一段代码&#xff0c;也可以在一个Action 执行前阻止其执行&#xff0c;同时也提供了一种可以提取Action中可重用部分代码的方式。…

java之拦截器

java里的拦截器是动态 拦截action的web请求&#xff0c;而过滤器能够进行系统级别的过滤&#xff0c;即能够过滤所有的web请求。从这可以看出拦截器是有一定的局限性的。拦截器是基于jdk实现的动态代理&#xff0c;拦截器是动态拦截action调用的对象&#xff0c; 拦截器可以使得…

Java三大器之拦截器(Interceptor)的实现原理及代码示例

前言&#xff1a;前面2篇博客&#xff0c;我们分析了Java中过滤器和监听器的实现原理&#xff0c;今天我们来看看拦截器。 1&#xff0c;拦截器的概念 java里的拦截器是动态拦截Action调用的对象&#xff0c;它提供了一种机制可以使开发者在一个Action执行的前后执行一段代…

Java 拦截器

一、引言 既然要用拦截器&#xff0c;首先先得简单了解一下什么是拦截器&#xff1a; 概念&#xff1a;java里的拦截器是动态拦截Action调用的对象&#xff0c;它提供了一种机制可以使开发者在一个Action执行的前后执行一段代码&#xff0c;也可以在一个Action执行前阻止其执行…

VirtualAPK:滴滴 Android 插件化的实践之路

作者简介&#xff1a; 任玉刚&#xff0c;滴滴出行 Android 技术专家&#xff0c;《Android 开发艺术探索》作者&#xff0c;插件化框架 dynamic-load-apk 的发起者&#xff0c;CSDN 移动开发博客专家&#xff0c;曾当选 CSDN 2014、2015年度十大博客之星。热爱技术&#xff0c…

Unity刚体

1、Dynamic&#xff1a;动态类型 受重力和力的影响移动和旋转 Material&#xff1a; 物理材质&#xff0c;在刚体上设置了物理材质&#xff0c;如果子物体有碰撞器但是没有设置材质则会通用刚体的物理材质 如果不设置&#xff0c;将使用在Physics 2D窗口中设置的默认材质(Physi…

android view 的测量过程

参考任玉刚主席的《android开发艺术探索》所写。

2017年终总结,开始写博客的第一年

结束校园生活&#xff0c;开始工作 今年是我开始工作的第一年&#xff0c;前半个学期实习阶段&#xff0c;开发了三个上线的应用&#xff0c;之前在学校的时候&#xff0c;做过不少练手的项目&#xff0c;有时心血来潮&#xff0c;还做了一些自己认为有趣的项目&#xff0c;但是…

阿里组织新调整:张勇兼任云业务总裁“敏捷组织”是内核

雷递网 雷建平 12月29日 岁末年初之际&#xff0c;在小米进行管理层调整后&#xff0c;阿里巴巴也进行了新一轮调整。 12月29日&#xff0c;阿里巴巴集团董事会主席兼CEO张勇发布内部邮件&#xff0c;宣布张建锋不再担任阿里云总裁&#xff0c;继续担任阿里达摩院院长&#xff…

鲲鹏院武志强课题组诚聘博士后

诚聘英才 Recruitment Season 佛山鲲鹏现代农业研究院 研究院简介 佛山鲲鹏现代农业研究院&#xff08;以下简称“鲲鹏院”&#xff09;成立于2021年&#xff0c;由中国农业科学院与佛山市人民政府、南海区人民政府依托中国农业科学院&#xff08;深圳&#xff09;农业基因组研…

刚体

概述 在整个 Unity 物理系统中&#xff0c;最重要概念就是刚体 Rigidbody。 刚体是物理学中的概念&#xff0c;它是指在运动中和受力后&#xff0c;形状和大小不变&#xff0c;并且内部各点相对位置不变的物体。刚体是一种为了方便物理计算而提出的理想化模型&#xff0c;在不…

技术人员如何从容转型项目经理?

科技在发展&#xff0c;时代在进步&#xff0c;项目越来越复杂&#xff0c;越来越多的技术人员面临技术转型&#xff0c;那么&#xff0c;如何成功转型成了众多技术人员面临的新挑战。 首先我们必须要搞清楚&#xff0c;为什么需要技术人员转型项目经理&#xff1f;项目经理不…

阿里云杨国彦:云上护航,陪伴成长

以下整理自杨国彦在云栖大会“云上成就创新梦想”论坛中发表的《云上护航&#xff0c;陪伴成长》的主题演讲&#xff09; 11月5日&#xff0c;以“云上成就创新梦想”为主题的中小企业云上创新论坛在浙江杭州云栖小镇举行&#xff0c;论坛聚集政府、资本、媒体、机构等相关领导…

滴滴技术专家任玉刚:让你的职业迷茫从哪来回哪去

今天给大家推荐的是《Android开发艺术探索》的作者&#xff08;滴滴技术专家&#xff09;任玉刚老师的直播课&#xff0c;感兴趣的同学可以通过文末的方式参与本次活动&#xff08;喜欢的同学欢迎转发&#xff09;。 我是任玉刚&#xff0c; 我来我想说。 01 收到过无数同学的…

从菜鸟到资深工程师的进阶之路

专访任玉刚&#xff1a;从菜鸟到资深工程师的进阶之路 发表于 2015-12-22 08:25| 11131次阅读| 来源 CSDN| 31 条评论| 作者 夏夏 专访 iOS Android 任玉刚 开发者 CSDN博客 allowtransparency"true" frameborder"0" scrolling"no" src"h…

kafka sasl_ssl配置

一、切换到存储证书的路径 我这里在家目录中的创建了ssl文件夹 mkdir ssl && cd ssl 二、生成服务端密钥库 keytool -keystore server.keystore.jks -alias localhost -validity 365 -genkey验证证书&#xff1a; keytool -list -v -keystore server.keystore.jks …

KAFKA SASL配置 记录

kafka配置SASL 第1步 将kafka_client_jaas.conf/kafka_server_jaas.conf/kafka_zoo_jaas.conf三个文件放入kafka的config文件夹中&#xff0c;文件中配置用户&#xff0c;superadmin用户必须配置。 kafka_client_jaas.conf内容如下 KafkaClient { …

WIN10 VS2019 编译Cyrus SASL

环境 下载安装Visual Studio 2019 安装时在【工作负载】必须勾选【使用C的桌面开发】下载cyrus-sasl源码 从Github上clone或者下载zip包&#xff0c;我本来是需要2.1.26&#xff0c;但是从从https://www.cyrusimap.org/releases/下载对应版本的源码包编译都有问题&#xff0c;…

Kafka3.0 SASL安全认证

下面主要介绍Kafka两种认证方式 kafka验证方式&#xff1a; SASL/PLAIN&#xff1a;不能动态添加用户配置文件写死账号密码 SASL/SCRAM&#xff1a; 可以动态的添加用户 SASL/PLAIN方式 cd /usr/local/kafka/kafka_2.12-3.0.1/bin/ ## 复制一份saslcp kafka-server-start.…