Spring Cloud OpenFeign调用接口时未发送audio/ogg请求头问题
问题:Feign Client发送OGG音频返回400错误(OGG header未找到)
通过Spring Cloud Feign Client调用API发送OGG音频字节时,收到400 Bad Request错误,错误信息:
"error_message" : "OGG header has not been found"
但使用Postman发送相同请求头和OGG文件时,请求正常。
FeignClient定义
@FeignClient(name = "${integration[0].speech.name}", url = "${integration[0].speech.url}", configuration = SpeechRecognizerConfig.class) public interface YandexSpeechRecognizerClient { @PostMapping @Headers({ "Content-Type", "audio/ogg" }) RecognizedTextResponse recognizeText(@RequestHeader("Authorization") String token, @RequestParam("lang") String lang, @RequestBody ByteArrayResource oggFileBytes); }
FeignClient配置
@Bean public Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } @Bean public Client httpFeignClient() { return new OkHttpClient(new okhttp3.OkHttpClient.Builder() .build()); } @Bean public Feign.Builder speechFeignBuilder(@Autowired Logger.Level logLevel, @Autowired Client client) { return Feign.builder() .logger(new Slf4jLogger(log)) .logLevel(logLevel) .client(client); }
测试方法
byte[] bytes = Files.readAllBytes(oggFile.toPath()); RecognizedTextResponse yandexRecognizedTextResponse = underTest.recognizeText( "Bearer " + authClient.getToken().getAccessToken(), "en-EN", false, false, "123123123", new ByteArrayResource(bytes) );
解决方案
核心原因
Feign处理ByteArrayResource类型的请求体时,会自动添加Content-Disposition等额外请求头,或对字节流做不必要的包装,导致服务端无法识别OGG文件的头部结构;而Postman是直接发送原始字节流,无额外处理,因此能正常解析。
具体修复步骤
修改Feign接口的请求体类型
将接口中@RequestBody ByteArrayResource oggFileBytes改为@RequestBody byte[] oggFileBytes,让Feign直接发送原始字节流:@PostMapping @Headers({ "Content-Type", "audio/ogg" }) RecognizedTextResponse recognizeText(@RequestHeader("Authorization") String token, @RequestParam("lang") String lang, @RequestBody byte[] oggFileBytes);调整测试方法的传参逻辑
测试时直接传递读取到的byte数组,无需包装成ByteArrayResource:byte[] bytes = Files.readAllBytes(oggFile.toPath()); RecognizedTextResponse yandexRecognizedTextResponse = underTest.recognizeText( "Bearer " + authClient.getToken().getAccessToken(), "en-EN", bytes );注:需确保测试方法参数数量、顺序与Feign接口完全匹配。
(可选)配置专属消息转换器
如果上述方法无效,添加专门处理音频字节流的消息转换器,避免默认转换器干扰:@Bean public HttpMessageConverters customConverters() { ByteArrayHttpMessageConverter converter = new ByteArrayHttpMessageConverter(); converter.setSupportedMediaTypes(Collections.singletonList(MediaType.parseMediaType("audio/ogg"))); return new HttpMessageConverters(converter); }利用日志对比请求差异
你已开启Feign全量日志,可重点排查:- 请求头是否与Postman完全一致(是否存在多余的
Content-Disposition等头) - 请求体字节流的MD5值是否与原文件一致,确认字节传输未被篡改
- 请求头是否与Postman完全一致(是否存在多余的
内容的提问来源于stack exchange,提问作者silenzzz
相关产品推荐
相关产品推荐

