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

如何提升Spring MVC中PathVariable参数的健壮性,兼容带非数字后缀的请求?

方案1:自定义路径变量转换器(Spring原生方案,最推荐)

Spring MVC 提供了Converter接口专门处理类型转换场景,不需要修改原有Controller代码,侵入性最低。

  • 第一步:自定义Long类型转换器,实现前缀数字提取逻辑
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

@Component
public class PrefixNumberConverter implements Converter<String, Long> {
    @Override
    public Long convert(String source) {
        StringBuilder numStr = new StringBuilder();
        for (char c : source.toCharArray()) {
            if (Character.isDigit(c)) {
                numStr.append(c);
            } else {
                break;
            }
        }
        if (numStr.length() == 0) {
            // 可根据业务需求调整无合法数字时的处理逻辑,比如抛自定义异常或返回默认值
            throw new IllegalArgumentException("路径参数无合法数字前缀");
        }
        return Long.parseLong(numStr.toString());
    }
}
  • 第二步:Spring Boot 会自动扫描标注了@Component的转换器并注册到MVC转换体系,原有Controller的@PathVariable Long id代码无需任何修改即可生效。

方案2:Filter全局预处理请求路径

如果需要对所有/api前缀的请求生效,可以通过过滤器修改请求路径,去掉数字后的冗余后缀再转发给对应接口:

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@WebFilter(urlPatterns = "/api/*")
public class PathTrimFilter implements Filter {
    private static final Pattern PATH_PATTERN = Pattern.compile("^/api/(\\d+).*$");

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String path = httpRequest.getRequestURI();
        Matcher matcher = PATH_PATTERN.matcher(path);
        if (matcher.matches()) {
            String newPath = "/api/" + matcher.group(1);
            HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper(httpRequest) {
                @Override
                public String getRequestURI() {
                    return newPath;
                }
                @Override
                public String getServletPath() {
                    return newPath;
                }
            };
            chain.doFilter(wrapper, response);
            return;
        }
        chain.doFilter(request, response);
    }
}

注意需要在项目启动类上添加@ServletComponentScan注解,才能扫描到@WebFilter标注的过滤器。

方案3:AOP拦截Controller方法替换参数

可以通过环绕通知拦截所有带@PathVariable Long id参数的Controller方法,在方法执行前提取参数中的数字部分替换原始值后再执行方法。这种方式需要匹配参数位置和注解,侵入性高于转换器方案,更适合需要做额外业务校验的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 21:54:04