Spring Cloud OpenFeign 在调用端点时不发送音频/ogg 标头

问题描述 投票:0回答:2

我正在尝试通过调用 API 通过 Spring Cloud Feign Client 发送音频 OGG 文件字节。

但是我得到了

400 Bad Request
,错误如下:

"error_message" : "OGG header has not been found"

尽管如此,如果 OGG 文件是从 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)
        );

我已经尝试了所有其他替代方案,但没有一个有效。

如何解决这个问题?

java spring spring-boot spring-cloud spring-cloud-feign
2个回答
0
投票

参考:https://github.com/spring-cloud/spring-cloud-openfeign/issues/889

根本原因:您正在尝试使用/混合Core FeignSpring Cloud Feign

这不会起作用。

不起作用的原因 -

@Headers
注释是
feign
包的一部分,而不是
org.springframework.cloud.openfeign
的一部分。


可能的解决方案:

第一个解决方案: Spring Cloud Feign 仅通过方法参数上的

@RequestHeader
支持标头。

将代码更新为:

FeignClient:

@FeignClient(name = "${integration[0].speech.name}",
        url = "${integration[0].speech.url}",
        configuration = SpeechRecognizerConfig.class)
public interface YandexSpeechRecognizerClient {

    @PostMapping
    RecognizedTextResponse recognizeText(@RequestHeader("Authorization") String token, 
                                         @RequestHeader("Content-Type") String contentType,
                                         @RequestParam("lang") String lang,
                                         @RequestBody ByteArrayResource oggFileBytes);

测试方法:

byte[] bytes = Files.readAllBytes(oggFile.toPath());
RecognizedTextResponse yandexRecognizedTextResponse = underTest.recognizeText(
                "Bearer " + authClient.getToken().getAccessToken(),
                "audio/ogg",
                "en-EN",
                false,
                false,
                "123123123",
                new ByteArrayResource(bytes)
        );

第二种解决方案:

您可以通过

spring.cloud.openfeign.client.config.{name}.defaultRequestHeaders
设置默认标头,该标头将随假客户端的每个请求一起发送。

示例:

application.yaml

spring:
    cloud:
        openfeign:
            client:
                config:
                    {name}:
                        .....
                        ......
                        defaultRequestHeaders:
                            Content-Type: audio/ogg

-1
投票
Feign 客户端方法上的

@Header
注释似乎没有按预期工作。您可以尝试以这种方式注入静态标头:

@PostMapping(headers = "content-type=audio/ogg")
// or
@PostMapping(produces = "audio/ogg")

另一种选择是在专用 FeignClientConfig 中使用

RequestInterceptor

@Bean
    public RequestInterceptor requestInterceptor() {
        return requestTemplate -> 
            requestTemplate.header("Content-Type", "audio/ogg");
    }

或在配置属性中指定默认标头,如下所示:

feign:
  client:
    config:
      your-client-name:
        Content-Type:
          - audio/ogg

但这两种方法的缺点是它们会影响同一假客户端的其他方法

© www.soinside.com 2019 - 2024. All rights reserved.