使用Spring RestTemplate PUT请求调用Apigee代理时遇404问题
问题排查:RestTemplate PUT请求带体时返回404且未到达Apigee
现象梳理
- 迁移API到Apigee后,RestTemplate发起带请求体+自定义头的PUT请求时,返回
HttpClientErrorException$NotFound: 404 Not Found: [no body],且请求未到达Apigee(仅授权令牌请求正常); - 若调用时不传请求体(
exchange的第三个参数传null),请求可正常到达Apigee; - 用Postman测试相同URL,请求正常触发Apigee监控。
可能的原因及解决方法
1. 请求头Content-Type未正确设置或不匹配
当带请求体发送请求时,Apigee可能要求特定的Content-Type(如application/json),若请求头中未显式设置,或序列化后的请求体格式与Content-Type不匹配,可能导致请求在到达Apigee前被拦截。
解决步骤:
- 在HttpHeaders中显式设置Content-Type:
headers.setContentType(MediaType.APPLICATION_JSON); - 检查headers中是否包含Apigee代理规则未允许的自定义头字段,如有则移除或在Apigee中配置允许。
2. UriComponentsBuilder构建URL时存在语法错误
你的代码中UriComponentsBuilder的pathSegment调用多了一个右括号:
.pathSegment("some-path", myId))
这可能导致生成的URL格式异常(如多余字符),虽然编译能通过,但实际请求路径错误引发404。
解决步骤:
- 修正代码,移除多余的右括号:
.pathSegment("some-path", myId) - 打印生成的
uri字符串,确认最终拼接的完整URL(rootUri + uri)格式正确,比如路径是否正确添加斜杠、无多余字符。
3. 请求体序列化异常
如果RestTemplate没有合适的HttpMessageConverter来序列化Customer对象,可能导致请求发送失败,错误被包装为404,且请求根本没发往Apigee。
解决步骤:
- 检查RestTemplate是否配置了对应格式的消息转换器,比如JSON格式需添加
MappingJackson2HttpMessageConverter:return restTemplateBuilder // 其他配置... .messageConverters(new MappingJackson2HttpMessageConverter()) .build(); - 尝试手动将
Customer序列化为JSON字符串后发送,验证是否能正常到达Apigee:ObjectMapper mapper = new ObjectMapper(); String customerJson = mapper.writeValueAsString(myCustomer); final HttpEntity<String> httpEntity = new HttpEntity<>(customerJson, headers); myRestTemplate.exchange(uri, HttpMethod.PUT, httpEntity, Void.class);
4. BufferingClientHttpRequestFactory的异常
你使用的缓冲请求工厂可能在处理带请求体的请求时出现异常,导致请求未正常发送。
解决步骤:
- 暂时移除
requestFactory(bufferingClientHttpRequestFactorySupplier)配置,使用默认请求工厂测试,若请求恢复正常,则排查该缓冲工厂的实现逻辑。
5. Apigee代理的特殊配置
虽然Postman测试正常,但RestTemplate的请求与Postman请求可能存在差异(如默认头字段、请求体编码等),Apigee的代理规则可能对PUT请求的体大小、格式有特殊限制。
解决步骤:
- 利用Apigee的Trace工具或日志系统,检查是否有请求被前置拦截器拒绝的记录;
- 确认Apigee代理是否允许PUT请求携带请求体,以及是否对Content-Type有强制要求。
内容的提问来源于stack exchange,提问作者Rlarroque
相关产品推荐
相关产品推荐

