使用IPv6地址访问Java Spring MVC应用时出现NumberFormatException异常
解决Spring MVC 4.2.1中IPv6访问引发的NumberFormatException问题
你遇到的问题是Spring MVC 4.2.1版本对IPv6格式的Origin头解析存在Bug:当通过带方括号的IPv6地址(比如[201:8008:78e4:61a4:8a21:6b6c:a853]:8080)访问应用并发起接口请求时,Spring的CORS检查逻辑会错误地把包含方括号的端口部分当成整数解析,从而抛出NumberFormatException。下面是几个可行的解决方案:
1. 升级Spring MVC版本(推荐方案)
Spring在4.3.x及以后的版本中修复了IPv6地址解析的问题,这是最彻底的解决办法。你可以把Spring相关依赖升级到4.3.x的稳定版本(比如4.3.30.RELEASE),框架会自动正确处理带方括号的IPv6 Origin头,无需额外修改代码。
如果使用Maven,只需修改pom.xml中的Spring版本号:
<properties> <spring.version>4.3.30.RELEASE</spring.version> </properties>
2. 自定义CorsProcessor绕过有Bug的同源检查逻辑
如果暂时无法升级Spring版本,可以自定义一个CorsProcessor替换默认实现,手动处理IPv6地址的解析:
步骤1:实现自定义CorsProcessor
import org.springframework.web.cors.DefaultCorsProcessor; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsUtils; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; public class IPv6CompatibleCorsProcessor extends DefaultCorsProcessor { @Override public boolean processRequest(CorsConfiguration config, HttpServletRequest request, HttpServletResponse response) throws IOException { if (CorsUtils.isCorsRequest(request)) { String origin = request.getHeader("Origin"); if (origin != null && origin.startsWith("[")) { try { // 手动解析IPv6格式的Origin地址 URI uri = new URI(origin); String host = uri.getHost(); int port = uri.getPort(); // 这里可添加自定义同源验证逻辑,比如对比应用的主机端口 return super.processRequest(config, request, response); } catch (URISyntaxException e) { // 解析失败时临时允许当前来源(可根据需求调整) response.setHeader("Access-Control-Allow-Origin", origin); response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization"); return true; } } } return super.processRequest(config, request, response); } }
步骤2:在Spring配置中注册自定义CorsProcessor
如果是XML配置:
<bean id="corsProcessor" class="com.yourpackage.IPv6CompatibleCorsProcessor"/> <mvc:cors> <mvc:mapping path="/**" processor="corsProcessor"/> </mvc:cors>
如果是Java配置类:
@Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { @Bean public CorsProcessor corsProcessor() { return new IPv6CompatibleCorsProcessor(); } @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**").corsProcessor(corsProcessor()); } }
3. 临时禁用CORS检查(仅测试环境使用)
如果你只是在测试环境验证功能,可以临时关闭CORS检查,但生产环境绝对不推荐这种方式,会带来安全风险。
可以在Controller方法上添加注解:
@CrossOrigin(origins = "*") @RequestMapping(value = "/your-api", method = RequestMethod.POST) public ResponseEntity<?> yourApiMethod() { // 接口逻辑 }
或者全局配置允许所有来源:
<mvc:cors> <mvc:mapping path="/**" allowed-origins="*"/> </mvc:cors>
验证修改
修改完成后重启应用,用IPv6地址访问并发起接口请求,检查是否还会抛出NumberFormatException异常。
内容的提问来源于stack exchange,提问作者Ronak Kagrana
相关产品推荐
相关产品推荐

