spring boot filter

spring boot filter 如何只拦截指定 url?
 
在 Spring Boot 中,你可以使用过滤器(Filter)来拦截特定的 URL 请求。下面为你详细介绍如何实现只拦截指定 URL 的过滤器。

步骤 1:创建过滤器类

首先,你需要创建一个实现 javax.servlet.Filter 接口的过滤器类。在该类中,你可以根据请求的 URL 进行判断,决定是否拦截请求。

java
 
 
 
 
 
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

// 使用 @WebFilter 注解指定过滤器名称和要拦截的 URL 模式
@WebFilter(filterName = "customFilter", urlPatterns = {"/api/specific/*"})
public class CustomFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化方法,可用于初始化资源
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String requestUrl = httpRequest.getRequestURI();

        // 打印当前请求的 URL
        System.out.println("拦截到的请求 URL: " + requestUrl);

        // 继续执行请求链
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        // 销毁方法,可用于释放资源
    }
}
 

代码解释

  • @WebFilter 注解:用于将该类标记为一个过滤器,并指定过滤器的名称和要拦截的 URL 模式。在上述示例中,urlPatterns = {"/api/specific/*"} 表示拦截以 /api/specific/ 开头的所有请求。
  • init(FilterConfig filterConfig) 方法:在过滤器初始化时调用,可用于初始化一些资源。
  • doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 方法:核心方法,用于处理请求和响应。在该方法中,首先将 ServletRequest 转换为 HttpServletRequest,以便获取请求的 URL。然后,你可以根据需要对请求进行处理,最后调用 chain.doFilter(request, response) 继续执行请求链。
  • destroy() 方法:在过滤器销毁时调用,可用于释放资源。

步骤 2:启用过滤器

为了让 Spring Boot 应用程序能够识别并使用该过滤器,你需要在主应用类上添加 @ServletComponentScan 注解。

java
 
 
 
 
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@SpringBootApplication
@ServletComponentScan
public class YourApplication {

    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }
}
 

步骤 3:使用 Java 配置方式(可选)

如果你不想使用 @WebFilter 注解,也可以通过 Java 配置的方式来注册过滤器。

java
 
 
 
 
 
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<CustomFilter> customFilterRegistration() {
        FilterRegistrationBean<CustomFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new CustomFilter());
        registration.addUrlPatterns("/api/specific/*");
        registration.setName("customFilter");
        registration.setOrder(1); // 设置过滤器的执行顺序
        return registration;
    }
}
 

代码解释

  • FilterRegistrationBean:用于注册过滤器的 Bean。
  • setFilter() 方法:设置要注册的过滤器实例。
  • addUrlPatterns() 方法:指定要拦截的 URL 模式。
  • setName() 方法:设置过滤器的名称。
  • setOrder() 方法:设置过滤器的执行顺序,数值越小越先执行。

通过以上步骤,你就可以实现只拦截指定 URL 的过滤器。
 
 
springboot 中 OncePerRequestFilter 可以只 拦截 指定的 url吗?
 
在 Spring Boot 中,OncePerRequestFilter 是 javax.servlet.Filter 的一个抽象实现类,它确保在一次请求中过滤器只被执行一次。可以使用 OncePerRequestFilter 来只拦截指定的 URL,下面为你介绍具体的实现方法。

实现思路

  1. 创建一个继承自 OncePerRequestFilter 的自定义过滤器类。
  2. 在 doFilterInternal 方法中,获取当前请求的 URL,判断该 URL 是否符合要拦截的规则,如果符合则进行相应处理,不符合则直接放行。

示例代码

1. 创建自定义过滤器类

java
 
 
 
 
 
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class CustomOncePerRequestFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        // 获取当前请求的 URL
        String requestUrl = request.getRequestURI();

        // 定义要拦截的 URL 规则,这里假设要拦截以 /api/sensitive 开头的 URL
        if (requestUrl.startsWith("/api/sensitive")) {
            System.out.println("拦截到敏感请求 URL: " + requestUrl);
            // 可以在这里添加对敏感请求的处理逻辑,例如验证请求参数、权限等
        }

        // 继续执行请求链
        filterChain.doFilter(request, response);
    }
}
 

2. 注册过滤器

可以通过 Java 配置的方式将自定义过滤器注册到 Spring Boot 应用中。

java
 
 
 
 
 
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());
        // 这里可以设置过滤器的 URL 匹配模式,不过最终还是会在过滤器内部根据具体逻辑判断
        registration.addUrlPatterns("/*"); 
        registration.setName("customOncePerRequestFilter");
        registration.setOrder(1); 
        return registration;
    }
}
 

代码解释

  • 自定义过滤器类
    • CustomOncePerRequestFilter 继承自 OncePerRequestFilter,并重写了 doFilterInternal 方法。
    • 在 doFilterInternal 方法中,通过 request.getRequestURI() 获取当前请求的 URL,然后使用 startsWith 方法判断该 URL 是否以 /api/sensitive 开头,如果是则进行相应处理。
    • 最后调用 filterChain.doFilter(request, response) 继续执行请求链。
  • 过滤器注册
    • FilterRegistrationBean 用于将自定义过滤器注册到 Spring Boot 应用中。
    • addUrlPatterns("/*") 表示该过滤器会拦截所有请求,但实际上会在过滤器内部根据具体的 URL 规则进行判断。
    • setName 方法设置过滤器的名称,setOrder 方法设置过滤器的执行顺序。

通过这种方式,你可以使用 OncePerRequestFilter 只拦截指定的 URL。
 
 
除了 OncePerRequestFilter,Spring Boot 中还有哪些类型的过滤器?
 
在 Spring Boot 中,除了 OncePerRequestFilter 之外,还有多种类型的过滤器,下面为你详细介绍:

1. 实现 javax.servlet.Filter 接口的普通过滤器

这是最基础的过滤器实现方式,javax.servlet.Filter 是 Servlet 规范定义的过滤器接口,所有过滤器都需要实现这个接口中的 doFilter 方法。

示例代码

java
 
 
 
 
 
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

public class SimpleFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化方法,可用于初始化资源
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        System.out.println("拦截到请求: " + httpRequest.getRequestURI());
        // 继续执行请求链
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        // 销毁方法,可用于释放资源
    }
}
 

注册方式

java
 
 
 
 
 
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<SimpleFilter> simpleFilterRegistration() {
        FilterRegistrationBean<SimpleFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new SimpleFilter());
        registration.addUrlPatterns("/*");
        registration.setName("simpleFilter");
        registration.setOrder(1);
        return registration;
    }
}
 

2. GenericFilterBean

GenericFilterBean 是 Spring 提供的一个抽象类,它实现了 javax.servlet.Filter 接口,并提供了一些便利的方法,比如自动注入 Spring 上下文的属性。开发者只需要继承 GenericFilterBean 并实现 doFilter 方法即可。

示例代码

java
 
 
 
 
 
import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

public class GenericFilterExample extends GenericFilterBean {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        System.out.println("GenericFilter 拦截到请求: " + httpRequest.getRequestURI());
        chain.doFilter(request, response);
    }
}
 

注册方式与普通过滤器类似

3. Spring Security 过滤器

Spring Security 是 Spring 生态中用于实现安全认证和授权的框架,它包含了一系列的过滤器,用于处理身份验证、授权、防止跨站请求伪造(CSRF)等安全相关的任务。

常见的 Spring Security 过滤器

  • UsernamePasswordAuthenticationFilter:用于处理基于表单的用户名和密码登录认证。
  • BasicAuthenticationFilter:用于处理 HTTP 基本认证。
  • CsrfFilter:用于防止跨站请求伪造攻击。

示例配置

java
 
 
 
 
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
           .authorizeRequests()
               .anyRequest().authenticated()
               .and()
           .formLogin();
        return httpSecurity.build();
    }
}
 

4. Spring MVC 拦截器(Interceptor)

虽然严格来说拦截器不属于传统意义上的 Servlet 过滤器,但在 Spring MVC 中,拦截器可以实现类似过滤器的功能,用于在请求处理前后进行一些通用的操作,如日志记录、权限验证等。拦截器需要实现 HandlerInterceptor 接口。

示例代码

java
 
 
 
 
 
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CustomInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("拦截器 - 预处理请求: " + request.getRequestURI());
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        System.out.println("拦截器 - 处理请求后");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                                Exception ex) throws Exception {
        System.out.println("拦截器 - 请求完成");
    }
}
 

注册方式

java
 
 
 
 
 
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 {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new CustomInterceptor())
               .addPathPatterns("/**");
    }
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

这些不同类型的过滤器和拦截器在 Spring Boot 应用中各有其适用场景,你可以根据具体需求选择合适的方式来实现请求的预处理和后处理。
 
在 Spring Boot 中,如何使用注解来配置过滤器?
如何获取请求的参数和头部信息?
如何配置过滤器的顺序?
 
posted @ 2025-05-08 15:06  CharyGao  阅读(70)  评论(0)    收藏  举报