Java使用RestTemplate请求第三方POST接口报405错误 Postman测试正常
问题场景
- 调用方式:Java代码中通过
RestTemplate向第三方服务发起REST调用 - 接口约定:目标接口要求请求方法为POST
- 对照验证:使用Postman携带相同参数、相同鉴权信息调用该接口,可正常返回响应,无报错
- 异常现象:代码发起请求时抛出
405 Method Not Allowed(方法不允许) - 现有实现代码:
RestTemplate restTemplate = new RestTemplate(); HttpHeaders headers = new HttpHeaders(); headers.add("Accept", MediaType.APPLICATION_JSON); headers.add("Cache-Control", "no-cache"); headers.add(CHIRAGH_CLIENT, AUTHENTICATION_SUCCESS); headers.add("Content-Type", "application/json"); headers.add("Accept", "*/*"); headers.add("Accept-Encoding", "gzip, deflate, br"); headers.add("Connection", "keep-alive"); headers.add("Authorization", "Bearer " + ChiraghConstants.BCI_AUTH_TOKEN); headers.add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"); HttpEntity<BlockChainSaveBidDTO> entity = new HttpEntity<>(event.getSaveBid(), headers); CompletableFuture res = restTemplate.postForObject( ChiraghConstants.BCI_BASE_URL + ChiraghConstants.BCI_AUCTION_BID_START +"/"+ event.getTokenId() + ChiraghConstants.BCI_AUCTION_BID_END , entity, CompletableFuture.class );
常见触发根因与修复方案
- URL拼接偏差触发重定向方法降级
拼接后的请求URL如果存在尾部多余斜杠、缺少协议前缀、路径分段错位的问题,会触发Nginx、Tomcat等服务组件的默认重定向逻辑。RestTemplate默认的请求工厂在跟随重定向时,会自动把原始POST请求降级为GET请求,最终命中服务端的405校验规则。可将代码拼接完成的最终URL通过日志打印出来,和Postman地址栏的URL逐字符比对,修正路径拼接错误即可。 - 重复定义的Header触发网关拦截
代码中两次添加Accept请求头,先后设置了application/json和*/*两个值。部分企业级网关对重复同名Header的校验规则较严格,会直接判定请求非法返回405;而Postman遇到重复同名Header时会自动保留最后一次设置的值,不会触发拦截。修复时需删除重复的Header键,每个Header仅保留一个最终生效值。 - 返回值类型定义错误引发序列化异常
RestTemplate是同步阻塞的HTTP客户端,调用方法本身不会返回CompletableFuture类型。代码中硬设置返回类型为CompletableFuture.class,会触发消息转换器的反序列化逻辑偏差,甚至部分拦截器会识别到异常请求结构直接返回405。需将返回类型替换为接口实际返回的业务类,不要强行转换为不匹配的类型。 - 手动设置连接头引发协议兼容问题
代码中手动添加了Connection: keep-alive请求头,部分旧版本网关会识别到客户端手动设置的连接标识,触发HTTP协议兼容逻辑,把原始POST请求降级为OPTIONS预检请求,若预检未通过则直接返回405。可删除该手动添加的连接头,交由底层HTTP客户端自动管理连接策略即可。 - 默认RestTemplate实例的兼容性问题
直接通过new RestTemplate()创建的实例,采用默认的消息转换器列表,部分场景下会错误识别请求体格式,导致服务端校验请求的Content-Type不匹配时返回405。替换为Spring容器中托管的、提前配置好消息转换器的RestTemplate实例,可规避默认实现的兼容问题。
快速验证步骤
- 日志输出最终拼接完成的完整请求URL,和Postman的请求地址逐字符比对
- 整理请求Header列表,删除重复的同名键,模拟和Postman完全一致的Header结构
- 打开RestTemplate的请求日志,对比实际发出的请求方法、Content-Type、序列化后的请求体,和Postman控制台展示的请求参数逐一核对
- 临时关闭RestTemplate的自动重定向开关,验证是否为重定向引发的方法降级问题
内容的提问来源于stack exchange,提问作者Noob
相关产品推荐
相关产品推荐

