You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring框架无需Spring Security,如何在Servlet过滤器中指定HTTP方法?

非Spring Security环境下为过滤器指定HTTP请求方法的优雅方案

问题背景

在Spring Security中,我们可以通过antMatcher轻松为过滤器的URL映射指定GET/POST/PUT等HTTP方法,仅让特定方法的请求触发过滤器逻辑。但脱离Spring Security环境时,如何实现同样的效果?是否只能在OncePerRequestFilter的doFilterInternal方法里通过繁琐的switch判断请求方法?

比如之前的判断代码:

switch(request.getMethod()) {
   ...
}

以及现有的FilterRegistrationBean配置:

@Bean
public FilterRegistrationBean<CustomFilter> registrationBean(){
    FilterRegistrationBean<CustomFilter> registration = new FilterRegistrationBean<>();
    registration.setFilter(customFilter);
    registration.addUrlPatterns("/open/*");
    /*may be it is possible to addHttpMethods?*/
    registration.setName("customLoggingFilter");
    registration.setOrder(2);
    return registration;
}

优雅解决方案

方案一:自定义RequestMatcher分离匹配逻辑

Spring的FilterRegistrationBean本身没有直接提供HTTP方法配置API,但可以通过自定义RequestMatcher实现URL与HTTP方法的联合匹配,避免在过滤器内部写硬编码判断。

  1. 实现自定义匹配器
public class MethodAndUrlMatcher implements RequestMatcher {
    private final AntPathMatcher pathMatcher = new AntPathMatcher();
    private final Set<String> allowedMethods;
    private final String urlPattern;

    public MethodAndUrlMatcher(String urlPattern, String... allowedMethods) {
        this.urlPattern = urlPattern;
        this.allowedMethods = Set.of(allowedMethods);
    }

    @Override
    public boolean matches(HttpServletRequest request) {
        boolean urlMatches = pathMatcher.match(urlPattern, request.getServletPath());
        boolean methodMatches = allowedMethods.contains(request.getMethod());
        return urlMatches && methodMatches;
    }
}
  1. 在自定义过滤器中注入匹配器
@Component
public class CustomFilter extends OncePerRequestFilter {
    private final MethodAndUrlMatcher matcher;

    // 初始化时指定要匹配的URL和允许的HTTP方法
    public CustomFilter() {
        this.matcher = new MethodAndUrlMatcher("/open/*", "GET", "POST");
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        if (matcher.matches(request)) {
            // 执行你的过滤器核心逻辑
            // 示例:记录请求信息
            System.out.println("处理请求:" + request.getMethod() + " " + request.getServletPath());
        }
        filterChain.doFilter(request, response);
    }
}
  1. 保持原有FilterRegistrationBean配置不变即可,匹配逻辑已交由MethodAndUrlMatcher处理。

方案二:扩展FilterRegistrationBean实现方法配置

如果希望直接在注册Bean的层面配置HTTP方法,可以扩展FilterRegistrationBean,添加方法匹配逻辑:

  1. 扩展FilterRegistrationBean
public class MethodFilterRegistrationBean<T extends Filter> extends FilterRegistrationBean<T> {
    private Set<String> allowedMethods;
    private final AntPathMatcher pathMatcher = new AntPathMatcher();

    public void setAllowedMethods(String... methods) {
        this.allowedMethods = Set.of(methods);
    }

    @Override
    public boolean matches(HttpServletRequest request) {
        // 先判断URL是否匹配
        boolean urlMatches = super.matches(request);
        if (!urlMatches) {
            return false;
        }
        // 再判断HTTP方法是否在允许列表中
        return allowedMethods == null || allowedMethods.contains(request.getMethod());
    }
}
  1. 使用扩展类配置过滤器
@Bean
public MethodFilterRegistrationBean<CustomFilter> registrationBean(CustomFilter customFilter){
    MethodFilterRegistrationBean<CustomFilter> registration = new MethodFilterRegistrationBean<>();
    registration.setFilter(customFilter);
    registration.addUrlPatterns("/open/*");
    // 直接指定允许的HTTP方法
    registration.setAllowedMethods("GET", "POST");
    registration.setName("customLoggingFilter");
    registration.setOrder(2);
    return registration;
}

这种方式下,过滤器只会处理符合URL规则且HTTP方法在允许列表中的请求,无需在过滤器内部添加判断逻辑。

补充说明

原生Servlet的FilterRegistration接口本身并没有提供指定HTTP方法的配置项,因此必须通过自定义匹配逻辑实现上述效果。相比在过滤器内部写switch判断,上面两种方案更符合单一职责原则,也更便于后续维护和扩展。

内容的提问来源于stack exchange,提问作者Bogdan Zaranik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 05:01:36