Spring Boot中如何在Controller前修改请求参数名称?
实现Spring Boot请求参数名称格式转换(
[]转.) 当然可以实现这个需求,核心思路是通过自定义HttpServletRequestWrapper包装原请求,修改参数名称的格式后,再通过Filter将包装后的请求传递给后续Spring MVC处理流程,这样就能让@ModelAttribute正常绑定参数。
具体实现步骤
1. 自定义HttpServletRequestWrapper重写参数处理逻辑
这个类负责将search[value]格式的参数名替换为search.value:
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.util.*; public class ParameterRewriteRequestWrapper extends HttpServletRequestWrapper { private final Map<String, String[]> modifiedParams; public ParameterRewriteRequestWrapper(HttpServletRequest request) { super(request); modifiedParams = rewriteParamNames(request.getParameterMap()); } private Map<String, String[]> rewriteParamNames(Map<String, String[]> originalParams) { Map<String, String[]> newParams = new HashMap<>(); for (Map.Entry<String, String[]> entry : originalParams.entrySet()) { // 把所有[xxx]格式的后缀替换为.xxx String newName = entry.getKey().replaceAll("\\[(.*?)\\]", ".$1"); newParams.put(newName, entry.getValue()); } return newParams; } @Override public String getParameter(String name) { String[] values = modifiedParams.get(name); return values != null && values.length > 0 ? values[0] : null; } @Override public String[] getParameterValues(String name) { return modifiedParams.get(name); } @Override public Map<String, String[]> getParameterMap() { return Collections.unmodifiableMap(modifiedParams); } }
2. 自定义Filter替换请求对象
通过Filter拦截请求,将原HttpServletRequest替换为上面定义的包装类:
import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException; public class ParameterRewriteFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (request instanceof HttpServletRequest) { HttpServletRequest wrappedRequest = new ParameterRewriteRequestWrapper((HttpServletRequest) request); chain.doFilter(wrappedRequest, response); } else { chain.doFilter(request, response); } } @Override public void init(FilterConfig filterConfig) throws ServletException {} @Override public void destroy() {} }
3. 注册Filter到Spring容器
有两种注册方式可选:
方式一:使用@ServletComponentScan
在启动类添加注解,扫描@WebFilter标记的Filter:
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); } }
同时在ParameterRewriteFilter类上添加@WebFilter(urlPatterns = "/*"),指定生效的路径(比如只对/api/*生效可以修改为/api/*)。
方式二:使用@Bean注册
在配置类中手动注册Filter,无需@ServletComponentScan:
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<ParameterRewriteFilter> parameterRewriteFilter() { FilterRegistrationBean<ParameterRewriteFilter> registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new ParameterRewriteFilter()); registrationBean.addUrlPatterns("/*"); // 按需修改生效路径 registrationBean.setOrder(1); // 确保在Spring MVC核心处理流程前执行 return registrationBean; } }
效果验证
当请求携带参数search[value]=test&search[regex]=false时,经过上述处理后,参数名会被转换为search.value和search.regex,你的Controller中@ModelAttribute Search search就能正常绑定这两个参数值。
注意事项
- 该逻辑支持嵌套参数转换,比如
search[sub][key]会被转为search.sub.key,适配多层级实体类绑定。 - 若仅需对特定接口生效,修改Filter的
urlPatterns即可,避免全局影响。 - 确保Filter的执行顺序优先于Spring MVC的DispatcherServlet(通过
setOrder设置较小的数值),否则参数绑定完成后再修改就无效了。
内容的提问来源于stack exchange,提问作者mehnet ali
相关产品推荐
相关产品推荐

