在spring boot应用中,web拦截器(interceptor)是一种用于在请求处理的不同阶段执行自定义逻辑的机制。拦截器广泛应用于各种场景,以增强应用的功能性、安全性和可维护性。
在spring boot项目中实现wen拦截器主要有以下几种方式
- 实现
handlerinterceptor接口 - 使用过滤器(
filter) - 使用
@aspect注解实现aop拦截
这里主要介绍 handlerinterceptor 接口 和 filter
一、实现 handlerinterceptor 接口
这是最常见和直接的方式。需要创建一个类实现 org.springframework.web.servlet.handlerinterceptor 接口,并重写其中的方法:
1、创建handlerinterceptor实现类 myinterceptor
import jakarta.servlet.http.httpservletrequest;
import jakarta.servlet.http.httpservletresponse;
import lombok.extern.slf4j.slf4j;
import org.springframework.stereotype.component;
import org.springframework.web.servlet.handlerinterceptor;
import org.springframework.web.servlet.modelandview;
@slf4j
@component
public class myinterceptor implements handlerinterceptor {
@override
public boolean prehandle(httpservletrequest request, httpservletresponse response, object handler) throws exception {
log.info("prehandle");
return handlerinterceptor.super.prehandle(request, response, handler);
}
@override
public void posthandle(httpservletrequest request, httpservletresponse response, object handler, modelandview modelandview) throws exception {
log.info("posthandle");
handlerinterceptor.super.posthandle(request, response, handler, modelandview);
}
@override
public void aftercompletion(httpservletrequest request, httpservletresponse response, object handler, exception ex) throws exception {
log.info("aftercompletion");
handlerinterceptor.super.aftercompletion(request, response, handler, ex);
}
}2、注册拦截器
实现完拦截器后,需要将其注册到spring mvc的配置中。可以通过继承 webmvcconfigurer 接口并重写 addinterceptors 方法来完成:
import jakarta.annotation.resource;
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 {
@resource
private myinterceptor myinterceptor;
@override
public void addinterceptors(interceptorregistry registry) {
registry.addinterceptor(myinterceptor)
.addpathpatterns("/**")//拦截所有请求
.excludepathpatterns("/login");// 放行登录请求
}
}这里的myinterceptor 也可以直接
new myinterceptor()
3、运行测试
myinterceptor : prehandle myinterceptor : posthandle myinterceptor : aftercompletion
二、使用过滤器(filter)
虽然过滤器不属于拦截器的范畴,但在spring boot中,过滤器也是常用的请求处理组件。可以通过实现 javax.servlet.filter 接口来创建自定义过滤器:
1、创建过滤器实现类
这里我创建了3个测试过滤器,分别是 myfilter、myfilter2、myfilter2,代码都是相同的,只是打印内容不一样
@slf4j
public class myfilter implements filter {
@override
public void dofilter(servletrequest servletrequest, servletresponse servletresponse, filterchain filterchain) throws ioexception, servletexception {
// 请求前处理
log.info("myfilter dofilter pre");
filterchain.dofilter(servletrequest, servletresponse);
// 响应后处理
log.info("myfilter dofilter after");
}
}2、使用@component 注解配置过滤器
通过将过滤器类声明为spring组件,spring boot会自动检测并注册它。
import org.springframework.stereotype.component;
@component
public class myfilter implements filter {
// 实现方法同上
}注意:默认情况下,使用@component注册的过滤器会被添加到过滤链中,但顺序可能不确定。如果需要指定顺序,建议使用其他注册方式。
3、通过配置类注册过滤器(filterregistrationbean)
通过filterregistrationbean可以更灵活地注册过滤器,包括设置过滤器的顺序、url模式等。
- 可以精确控制过滤器的顺序。
- 可以指定过滤器应用的url模式。
import org.springframework.boot.web.servlet.filterregistrationbean;
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
@configuration
public class filterconfig {
@bean
public filterregistrationbean<myfilter> myfilter() {
filterregistrationbean<myfilter> bean = new filterregistrationbean<>();
bean.setfilter(new myfilter());
bean.addurlpatterns("/*"); // 拦截所有请求
bean.setorder(1); // 设置过滤器顺序,数值越小优先级越高
return bean;
}
@bean
public filterregistrationbean<myfilter2> myfilter2() {
filterregistrationbean<myfilter2> bean = new filterregistrationbean<>();
bean.setfilter(new myfilter2());
bean.addurlpatterns("/*");
bean.setorder(2);
return bean;
}
@bean
public filterregistrationbean<myfilter3> myfilter3() {
filterregistrationbean<myfilter3> bean = new filterregistrationbean<>();
bean.setfilter(new myfilter3());
bean.addurlpatterns("/*");
bean.setorder(3);
return bean;
}
}运行测试
通过日志可以看见,order值越小优先级越高,过滤器的执行遵循先进后出的原则
c.hj.springboot3.filter.demo2.myfilter : myfilter dofilter pre
c.hj.springboot3.filter.demo2.myfilter2 : myfilter2 dofilter pre
c.hj.springboot3.filter.demo2.myfilter3 : myfilter3 dofilter pre
c.h.s.filter.service.userserviceimpl : 执行业务代码
c.hj.springboot3.filter.demo2.myfilter3 : myfilter3 dofilter after
c.hj.springboot3.filter.demo2.myfilter2 : myfilter2 dofilter after
c.hj.springboot3.filter.demo2.myfilter : myfilter dofilter after
三、使用onceperrequestfilter
onceperrequestfilter 是 spring 框架提供的一个非常有用的过滤器基类,旨在确保某个过滤器在每个 http 请求中只执行一次。这在需要确保某些处理逻辑(如身份验证、日志记录、请求修改等)在整个请求生命周期中不被重复执行时特别有用。
它的主要功能是确保其 dofilterinternal 方法在每个请求中仅被调用一次。这是通过检查请求属性来实现的,防止在某些情况下(如转发请求)过滤器被多次执行。
1. 主要方法
dofilterinternal(httpservletrequest request, httpservletresponse response, filterchain filterchain):这是需要子类实现的方法,在其中编写自定义的过滤逻辑。该方法保证在每个请求中只被调用一次。shouldnotfilter(httpservletrequest request):可以重写此方法来指定某些请求不需要被过滤。dofilter(httpservletrequest request, httpservletresponse response, filterchain filterchain):这是 filter 接口的方法,onceperrequestfilter 已经实现了该方法,确保 dofilterinternal 只执行一次。
2. 使用 onceperrequestfilter
2.1 创建自定义过滤器
要使用 onceperrequestfilter,通常需要创建一个继承自它的子类,并实现 dofilterinternal 方法。
示例代码:
import javax.servlet.filterchain;
import javax.servlet.servletexception;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
import org.springframework.web.filter.onceperrequestfilter;
import java.io.ioexception;
public class customonceperrequestfilter extends onceperrequestfilter {
@override
protected void dofilterinternal(httpservletrequest request,
httpservletresponse response,
filterchain filterchain)
throws servletexception, ioexception {
// 请求预处理逻辑
system.out.println("customonceperrequestfilter: 请求前处理");
// 继续过滤器链
filterchain.dofilter(request, response);
// 响应后处理逻辑
system.out.println("customonceperrequestfilter: 响应后处理");
}
}2.2 注册自定义过滤器
创建完自定义过滤器后,需要将其注册到 spring boot 应用中。可以使用 filterregistrationbean 进行注册。
示例代码:
import org.springframework.boot.web.servlet.filterregistrationbean;
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
@configuration
public class filterconfig {
@bean
public filterregistrationbean<customonceperrequestfilter> customfilterregistration() {
filterregistrationbean<customonceperrequestfilter> registration = new filterregistrationbean<>();
registration.setfilter(new customonceperrequestfilter());
registration.addurlpatterns("/*"); // 拦截所有请求
registration.setname("customonceperrequestfilter");
registration.setorder(1); // 设置过滤器顺序
return registration;
}
}四、其他类似过滤器
1、characterencodingfilter
简介:characterencodingfilter 用于设置请求和响应的字符编码,确保请求参数和响应内容的编码一致,防止乱码问题。
使用场景:在处理国际化应用或需要特定字符编码的场景下非常有用。
示例配置:
import org.springframework.boot.web.servlet.filterregistrationbean;
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import org.springframework.web.filter.characterencodingfilter;
@configuration
public class encodingfilterconfig {
@bean
public filterregistrationbean<characterencodingfilter> characterencodingfilter() {
characterencodingfilter filter = new characterencodingfilter();
filter.setencoding("utf-8");
filter.setforceencoding(true);
filterregistrationbean<characterencodingfilter> registration = new filterregistrationbean<>(filter);
registration.addurlpatterns("/*");
registration.setname("characterencodingfilter");
registration.setorder(1);
return registration;
}
}2、hiddenhttpmethodfilter
简介:hiddenhttpmethodfilter 用于将带有特殊参数(如 _method)的 post 请求转换为对应的 http 方法(如 put、delete)。这在 html 表单不支持某些 http 方法时非常有用。
使用场景:在使用 restful api 且前端仅支持 post 请求时,通过隐藏字段指定实际的 http 方法。
启用方式:
在 spring boot 中,默认情况下,hiddenhttpmethodfilter 是启用的。如果需要自定义,可以手动注册:
@bean
public hiddenhttpmethodfilter hiddenhttpmethodfilter() {
return new hiddenhttpmethodfilter();
}3、corsfilter
简介:corsfilter 用于处理跨域资源共享(cors)配置,允许或限制来自不同源的请求。
使用场景:在构建需要与前端分离的应用,且前端和后端部署在不同域时。
示例配置:
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import org.springframework.web.cors.corsconfiguration;
import org.springframework.web.cors.urlbasedcorsconfigurationsource;
import org.springframework.web.filter.corsfilter;
@configuration
public class corsconfig {
@bean
public corsfilter corsfilter() {
urlbasedcorsconfigurationsource source = new urlbasedcorsconfigurationsource();
corsconfiguration config = new corsconfiguration();
config.setallowcredentials(true);
config.addallowedorigin("http://example.com");
config.addallowedheader("*");
config.addallowedmethod("*");
source.registercorsconfiguration("/**", config);
return new corsfilter(source);
}
}到此这篇关于springboot项目web拦截器使用的文章就介绍到这了,更多相关springboot web拦截器内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论