Spring Boot中CORSFilter致路径变量为null的原因咨询
当发送请求http://localhost:8080/api/v1/users/info/7时,路径变量userId(int类型)被置为null,触发可选int类型参数无法转为null的错误,且问题定位到自定义CORSFilter中的super.doFilter(request, response, chain)语句,核心原因如下:
1. 请求对象被包装但未传递路径变量属性
如果你的CORSFilter继承了OncePerRequestFilter这类父类,调用super.doFilter时,父类内部可能会对HttpServletRequest进行包装(比如生成处理跨域的自定义请求对象)。但这类包装过程如果没有复制原请求中存储路径变量的关键属性——HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE(该属性存储着DispatcherServlet解析出的路径变量键值对),后续Controller就无法从包装后的请求中获取到正确的路径变量值,最终得到null。
2. 自定义请求包装类未正确重写方法
若你在CORSFilter中手动使用HttpServletRequestWrapper包装请求,但没有重写getAttribute()方法来传递HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE对应的属性,那么当super.doFilter执行后,包装后的请求无法返回已解析的路径变量,DispatcherServlet会重新解析但无法得到正确结果,导致路径变量为null。而int作为基本数据类型不能接收null,直接抛出错误。
3. Filter执行顺序干扰路径变量解析
如果自定义CORSFilter的执行顺序早于RequestMappingHandlerMapping(负责解析路径变量的组件),且Filter中修改了请求URL或请求对象却未保留路径变量的解析状态,当DispatcherServlet处理请求时,会因为请求对象已被修改而无法正确提取路径变量,最终返回null。
验证方向
- 检查CORSFilter的父类实现,确认
doFilterInternal方法是否对请求进行了包装,是否遗漏了路径变量属性的传递。 - 若使用了
HttpServletRequestWrapper,查看是否重写了getAttribute()方法,确保能返回HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE对应的属性值。 - 在Filter中分别打印原请求和包装后请求的
getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE)值,对比是否出现属性丢失的情况。
内容的提问来源于stack exchange,提问作者Damika

