一般网站版式有哪几种,厦门市建设工程造价信息网,中国建设行业信息网站,石家庄房产网新楼盘在售楼盘Spring Boot拦截器#xff08;Interceptor#xff09;的概念
- 在Spring Boot中#xff0c;拦截器是一种AOP的实现方式。它主要用于font stylecolor:#DF2A3F;拦截请求/font#xff0c;在请求处理之前和之后执行特定的代码逻辑。与过滤器不同的…Spring Boot拦截器Interceptor的概念
- 在Spring Boot中拦截器是一种AOP的实现方式。它主要用于font stylecolor:#DF2A3F;拦截请求/font在请求处理之前和之后执行特定的代码逻辑。与过滤器不同的是拦截器更侧重于对Spring MVC中的font stylecolor:#DF2A3F;控制器Controller/font进行拦截能够访问到Spring MVC上下文中的对象比如获取请求的处理器Handler信息、模型Model和视图View相关信息等。创建拦截器类
- 要创建拦截器需要实现HandlerInterceptor接口。这个接口有三个方法* font stylecolor:#DF2A3F;preHandle()/font在请求处理之前调用。可以进行权限验证、日志记录等操作。如果返回false则请求被中断不会继续执行后续的处理器Controller方法如果返回true则请求继续传递。* font stylecolor:#DF2A3F;postHandle()/font在请求处理之后视图渲染之前调用。可以对模型Model和视图View进行修改等操作。* font stylecolor:#DF2A3F;afterCompletion()/font在整个请求完成后包括视图渲染后调用。主要用于资源清理等操作。
- 例如创建一个简单的拦截器来记录请求处理时间RequestTimeInterceptor对象public class RequestTimeInterceptor implements HandlerInterceptor {private Date startTime;Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {startTime new Date();return true;}Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {Date endTime new Date();System.out.println(Request processing time: (endTime.getTime() - startTime.getTime()) ms);}Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 可以在这里进行资源清理等操作}
}配置拦截器
方式一通过实现WebMvcConfigurer接口
- 创建一个配置类实现WebMvcConfigurer接口。
- 在addInterceptors方法中添加拦截器并配置拦截路径。
- 例如Configuration
public class InterceptorConfig implements WebMvcConfigurer {Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new RequestTimeInterceptor()).addPathPatterns(/**);}
}上述代码中addInterceptor方法添加了RequestTimeInterceptor拦截器addPathPatterns方法指定了拦截的路径为所有路径/**。
方式二通过扩展WebMvcConfigurationSupport类不推荐可能会覆盖Spring Boot的默认配置 创建一个配置类继承自WebMvcConfigurationSupport。重写addInterceptors方法来配置拦截器。例如 public class InterceptorConfiguration extends WebMvcConfigurationSupport {Overrideprotected void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new RequestTimeInterceptor()).addPathPatterns(/**);}
}- 不过这种方式可能会导致Spring Boot自动配置的一些Web相关的配置失效如静态资源处理等所以一般推荐使用第一种方式。拦截器的执行顺序
- 当有多个拦截器时它们的执行顺序是按照在InterceptorRegistry中添加的顺序来执行的。先添加的拦截器先执行preHandle方法后执行postHandle和afterCompletion方法。例如假设有拦截器Interceptor1和Interceptor2配置如下Configuration
public class InterceptorConfig implements WebMvcConfigurer {Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new Interceptor1()).addPathPatterns(/**);registry.addInterceptor(new Interceptor2()).addPathPatterns(/**);}
}- 在这个例子中Interceptor1的preHandle方法会先于Interceptor2的preHandle方法执行。而Interceptor2的postHandle和afterCompletion方法会先于Interceptor1的相应方法执行。过滤器 Filter 的概念
在 Spring Boot 中过滤器是一种用于拦截和处理请求和响应的组件。它可以在请求到达控制器Controller之前进行预处理例如验证请求头、验证用户身份等也可以在响应返回客户端之前进行后处理例如修改响应头、添加日志信息等。过滤器可以对多个请求和响应进行统一的处理是实现横切关注点如安全、日志记录等的重要手段。
实现Filter接口并使用WebFilter注解原生servlet配置方式
- **使用注解方式推荐**- 在Spring Boot中更方便的是使用WebFilter注解来创建过滤器。例如- javaWebFilter(urlPatterns /*)public class MyFilter implements Filter {Overridepublic void init(FilterConfig filterConfig) throws ServletException {// 初始化方法在过滤器初始化时调用可以进行一些初始化操作如加载配置文件等}Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {// 过滤方法在这里可以对请求进行处理然后决定是否将请求传递给下一个过滤器或控制器// 例如可以在这里检查请求头中的令牌Token是否有效filterChain.doFilter(servletRequest, servletResponse);// 在调用filterChain.doFilter后可以对响应进行处理}Overridepublic void destroy() {// 销毁方法在过滤器销毁时调用可以进行一些资源释放等}}其中WebFilter(urlPatterns /*)注解用于指定过滤器要拦截的 URL 模式/*表示拦截所有的请求路径。自动配置使用WebFilter注解的过滤器 需要在 Spring Boot 的主应用程序类上添加ServletComponentScan注解这样 Spring Boot 才能扫描到过滤器并自动进行配置。例如 SpringBootApplication
ServletComponentScan
public class MySpringBootApp {public static void main(String[] args) {SpringApplication.run(MySpringBootApp.class, args);}
}手动配置通过FilterRegistrationBean 有时候可能需要更灵活的配置例如设置过滤器的执行顺序、添加初始化参数等。可以通过FilterRegistrationBean对象 来手动配置过滤器。例如font stylecolor:rgb(38, 38, 38);background-color:rgb(242, 242, 247);FilterRegistrationBean对象可以/font 设置实际过滤器 setFilter(设置过滤器名 setName(“myFilter”);设置过滤路径 addUrlPatterns(“/*”);设置优先级 setOrder(1); Configuration
public class FilterConfig {Beanpublic FilterRegistrationBeanMyFilter myFilterRegistration() {FilterRegistrationBeanMyFilter registrationBean new FilterRegistrationBean();registrationBean.setFilter(new MyFilter());registrationBean.addUrlPatterns(/*);registrationBean.setName(myFilter);registrationBean.setOrder(1); // 设置过滤器的执行顺序数字越小越先执行return registrationBean;}
}过滤器链Filter Chain
- 当有多个过滤器时它们会形成一个过滤器链。请求会依次经过每个过滤器每个过滤器都可以对请求进行处理然后决定是否将请求传递给下一个过滤器。在doFilter方法中通过调用filterChain.doFilter(servletRequest, servletResponse)来将请求传递给下一个过滤器或控制器。如果某个过滤器没有调用这个方法那么请求就会被截断后续的过滤器和控制器都不会收到这个请求。同样在响应返回时也会按照相反的顺序经过各个过滤器每个过滤器可以对响应进行处理。例如假设有两个过滤器Filter1和Filter2请求首先会到达Filter1Filter1处理后传递给Filter2Filter2处理后传递给控制器响应返回时先经过Filter2再经过Filter1最后返回给客户端。**1.**通过xml文件配置过滤器链: * 创建两个过滤器CharacterEncodingFilter、LoggingFilterpublic class CharacterEncodingFilter implements Filter {private String encoding;Overridepublic void init(FilterConfig filterConfig) throws ServletException {encoding filterConfig.getInitParameter(encoding);}Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {servletRequest.setCharacterEncoding(encoding);filterChain.doFilter(servletRequest, servletResponse);}Overridepublic void destroy() {// 可以在这里进行资源释放等操作}
}public class LoggingFilter implements Filter {Overridepublic void init(FilterConfig filterConfig) throws ServletException {}Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println(Request received at: new Date());filterChain.doFilter(servletRequest, servletResponse);}Overridepublic void destroy() {}
}* **配置过滤器链在 web.xml 中*** 在这个配置中LoggingFilter会应用到所有的请求/*。CharacterEncodingFilter会应用到名为MyServlet的 Servlet。当请求到来时会先经过LoggingFilter然后根据请求的目标是MyServlet时再经过CharacterEncodingFilter。filterfilter - nameLoggingFilter/filter - namefilter - classcom.example.filters.LoggingFilter/filter - class
/filter
filter - mappingfilter - nameLoggingFilter/filter - nameurl - pattern/*/url - pattern
/filter - mappingfilterfilter - nameCharacterEncodingFilter/filter - namefilter - classcom.example.filters.CharacterEncodingFilter/filter - classinit - paramparam - nameencoding/param - nameparam - valueUTF - 8/param - value/init - param
/filter
filter - mappingfilter - nameCharacterEncodingFilter/filter - nameservlet - nameMyServlet/servlet - name
/filter - mapping上述代码中首先定义了一个名为CharacterEncodingFilter的过滤器并且通过init - param标签设置了一个初始化参数encoding为UTF - 8。然后通过filter - mapping标签将这个过滤器应用到所有的请求/*。当请求到来时这个过滤器会设置请求的字符编码为UTF - 8然后将请求传递给下一个过滤器或者目标资源。
**2.**使用注解方式Servlet 3.0实现过滤器链
- 当有多个注解式过滤器时过滤器的执行顺序是按照类名的字典序来确定的。如果需要更精确地控制顺序可以使用javax.annotation.Priority注解来指定优先级。数字越小优先级越高。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.annotation.WebFilter;
import javax.annotation.Priority;
import java.io.IOException;WebFilter(filterName AuthFilter, urlPatterns /*)
Priority(1)
public class AuthFilter implements Filter {//...
}WebFilter(filterName AnotherFilter, urlPatterns /*)
Priority(2)
public class AnotherFilter implements Filter {//...
}DelegatingFilterProxyRegistrationBean 对象代理过滤器。
DelegatingFilterProxyRegistrationBean 是 Spring Boot 中用于注册一个代理过滤器DelegatingFilterProxy的配置类。它主要用于将一个基于 Servlet 的过滤器集成到 Spring 的应用上下文中使得这个过滤器能够利用 Spring 的特性如依赖注入、配置属性等。这个类在将传统的 Servlet 过滤器与 Spring 应用进行整合时非常有用。例如在一些安全认证过滤器或者日志记录过滤器的场景下通过它可以更好地管理和配置这些过滤器让它们能够从 Spring 的环境配置如配置文件、环境变量等中获取必要的参数并且能够方便地与 Spring 管理的其他组件如服务层组件、数据源等进行交互。
·配置**DelegatingFilterProxyRegistrationBean**
假设我们有一个自定义的过滤器MyFilter并且希望通过DelegatingFilterProxyRegistrationBean 来注册它使其能够与 Spring 应用上下文集成。
1**.创建一个过滤器MyFilter** public class MyFilter implements Filter {Overridepublic void init(FilterConfig filterConfig) throws ServletException {// 初始化过滤器这里可以获取初始化参数等操作}Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {// 执行过滤操作例如检查请求头、验证用户身份等filterChain.doFilter(servletRequest, servletResponse);}Overridepublic void destroy() {// 销毁过滤器释放资源}
}2.然后在Spring Boot的配置类中注册DelegatingFilterProxyRegistrationBean
Configuration
public class FilterConfig {Beanpublic FilterRegistrationBeanDelegatingFilterProxy myFilterRegistration() {FilterRegistrationBeanDelegatingFilterProxy registrationBean new FilterRegistrationBean();DelegatingFilterProxy delegatingFilterProxy new DelegatingFilterProxy(myFilter);registrationBean.setFilter(delegatingFilterProxy);registrationBean.addUrlPatterns(/*);return registrationBean;}Bean(name myFilter)public MyFilter myFilter() {return new MyFilter();}
}在上述配置中首先创建了一个DelegatingFilterProxyRegistrationBean并将一个DelegatingFilterProxy 实例设置为其过滤器。DelegatingFilterProxy 的构造函数参数 myFilter 是要在 Spring 应用上下文中查找的真正过滤器 Bean 的名称。然后通过addUrlPatterns(/*) 设置了过滤器拦截的 URL 模式为所有请求。同时还通过Bean(name myFilter) 方法定义了真正的过滤器MyFilter这样DelegatingFilterProxy 就能在 Spring 应用上下文中找到它并进行委托。
DelegatingFilterProxyRegistrationBean的优点
1 .灵活性高它允许过滤器成为 Spring 的 Bean从而可以利用 Spring 的各种功能
2 .便与维护和管理。有多个过滤器需要集成和管理。