当前位置: 首页 > 知识库问答 >
问题:

如何将自定义Http客户端注入Spring Cloud openfeign?

施文彬
2023-03-14

我试图为Spring Cloud OpenFeign提供CloseableHttpClient。Spring Cloud Open Faign Documentation表示它支持CloeableHttpClient。Spring文档没有给出任何实际替换HTTP客户端的例子。

基本上,我将SSLContext提供给HTTP客户端,我想假装使用这个SSLContext加载的客户端。如何将这个CloseableHttpClient注入到外部?

以下是我的相关配置:

  1. 我正在使用SpringBootApp
@SpringBootApplication
@EnableFeignClients
public class Application extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
import org.springframework.cloud.openfeign.FeignClient;
//skipping rest of the imports for brevity
    @FeignClient(name ="remote-service", url = "${remote.service-url}", configuration = FeignConfig.class)
        public interface RemoteServiceApi {
            @GetMapping(value = "/api/v1/resources/{Id}")
            public String getResource(@PathVariable("Id") String Id);
        }
import org.apache.http.impl.client.CloseableHttpClient;
//skipping rest of the imports for brevity
public class FeignConfig {
    @Bean
    public CloseableHttpClient client() {
         CloseableHttpClient httpClient=null;
         try {
                    //... Skipping code for brevity.  
                    //here creating "sslSocketFactory" used in the HttpClient builder below
                    httpClient = HttpClients.custom().setSSLSocketFactory(sslSocketFactory)
                    .setMaxConnTotal(10)
                    .setMaxConnPerRoute(10)
                    .build();
                
            }catch(IOException | KeyManagementException | UnrecoverableKeyException | NoSuchAlgorithmException | KeyStoreException | CertificateException e) {
                System.err.println("Exception during creation of HttpClient. : "+e.getMessage());
            }
        return httpClient;
    }
}

我不明白的另一部分是,Spring将如何将这个定制的可关闭HttpClient挂接到它声称的伪装上。因为当我调试时,在运行时,我会看到带外文注释的接口是由外文实现的。SynchronousMethodHandler类和该类中的“客户机”字段的类型为false。客户端,并在运行时获取com。太阳安全ntlm。客户端(可能是默认实现)。如何关闭HttpClient应该被注射到外国。客户网络上很少有这样的例子,他们也没有解释。

我在SOF上找到了这个帖子但是

  1. 这里还注入了CloseableHttpClient类型的@Bean
  2. 对此没有有用的答案

共有3个答案

郦楷
2023-03-14

你需要把@Configuration放在FaignConfig上面,我相信这会让它工作。

乜昆
2023-03-14

我遇到了同样的问题(尽管使用OkHttpClient而不是ApacheHttpClient)。你的问答帮助了我。谢谢!

对我来说,关键是在自动配置类中,我们可以找到以下内容:

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(OkHttpClient.class)
@ConditionalOnMissingClass("com.netflix.loadbalancer.ILoadBalancer")
@ConditionalOnMissingBean(okhttp3.OkHttpClient.class)
@ConditionalOnProperty("feign.okhttp.enabled")
protected static class OkHttpFeignConfiguration {

...最感兴趣的是这一行:

@ConditionalOnMissingBean(okhttp3.OkHttpClient.class)

...当我们提供自己的超文本传输协议客户端bean时,这实际上使Spring忽略了该配置(如留档中所述)。

有趣的是,OkHttpFeignConfiguration本身负责将http客户机包装到它自己的包装器类中(正如您在自己的回答中所述):

@Bean
@ConditionalOnMissingBean(Client.class)
public Client feignClient(okhttp3.OkHttpClient client) {
    return new OkHttpClient(client);
}

因此,当我们提供自己的http客户机bean时,我们实际上禁用了包装器的自动实例化。由于Feign在应用程序上下文中找不到其客户机类型的bean,因此它自己创建了一个bean;默认值。客户因此,我们的http客户端bean实际上被忽略了。。。

我的解决方案是自己在配置中“包装”:

@Bean
fun feignClient(client: OkHttpClient) = feign.okhttp.OkHttpClient(client)

当这个bean出现在应用程序上下文中时,费恩将利用它,而不是创建它的默认客户端。

在ApacheHttpClient案例中,逻辑是完全相同的。

上述解决方案经过测试,可用于外部全局配置和特定于客户端的配置。

据我所知,留档没有提到我们必须自己配置这个“包装豆”。我可能错过了一些重要的东西,在某个地方,或者在库的最新版本中可能对这个beahviour进行了更改。

魏俊茂
2023-03-14

在我们注射的豆子中,我们必须提供假药。客户端的实现。最简单的是新客户端。默认值(SSLSocketFactory、HostnameVerifier)。我将问题中的httpClient@Bean注入代码更改为:

@Bean
    public CloseableHttpClient client() {
 CloseableHttpClient httpClient=null;
         try {
                    //... Skipping code for brevity.  
                    //here creating "sslSocketFactory" used in the HttpClient builder below
                    httpClient = HttpClients.custom().setSSLSocketFactory(sslSocketFactory)
                    .setMaxConnTotal(10)
                    .setMaxConnPerRoute(10)
                    .build();
                
            }catch(IOException | KeyManagementException | UnrecoverableKeyException | NoSuchAlgorithmException | KeyStoreException | CertificateException e) {
                System.err.println("Exception during creation of HttpClient. : "+e.getMessage());
            }
        return httpClient;
    }
              

致:

@Bean
    public feign.Client client() {
      
       feign.Client client=null;
        try {

      //... Skipping code for brevity.  
                    //here creating "sslSocketFactory" used in the HttpClient builder below
      client = new Client.Default(sslSocketFactory, new DefaultHostnameVerifier());
            
        }catch(IOException | KeyManagementException | UnrecoverableKeyException | NoSuchAlgorithmException | KeyStoreException | CertificateException e) {
            System.err.println("Exception during creation of HttpClient. : "+e.getMessage());
        }
}

经验教训:

当文档中说,“您可以通过在使用Apache时提供ClosableHttpClient的bean或在使用OK HTTP时提供OkHttpClient的bean来定制所使用的HTTP客户端。”

然后人们说他们提供了CloseableHttpClient,因为这个问题没有得到正确的回答。这种豆子注射剂永远不会起作用。

最重要的是,OpenFaigns的Github留档谈到了使用ApacheHttpClient。

这可能会让人感到困惑。我问题的第二部分“我不理解的另一部分,Spring将如何将这个定制的可关闭HttpClient挂接到它声称的佯装上……这个类中的'client'字段的类型是佯装.client”回答:

ApacheHttpClient OpenFeign Github文档所说的并不是什么魔法,而是ApacheHttpClient库ApacheHttpClient上的OpenFeign包装器,它实现了Faign。客户端接口。

这个ApacheHttpClient实现在openfeign的Spring Boot starter附带的Faign core 10.1.1依赖项中不可用。

 类似资料:
  • 我目前正在努力掌握Spring和Fign。开门见山:我正在努力修改这个项目中的“飞度客户端”: Walery的“飞度你好世界”,以便代替 维基百科 使用@Autowired表示法,类似于此处的一个表示法:部分名为:手动创建外部客户端 这样做的目的是稍后注入自定义解码器和编码器。我已经尝试了一段时间,我所能实现的就是破坏整个事情。 我从这里和那里收集了一些线索,并设法到达了创建Configurati

  • 本文向大家介绍Python HTTP客户端自定义Cookie实现实例,包括了Python HTTP客户端自定义Cookie实现实例的使用技巧和注意事项,需要的朋友参考一下 Python HTTP客户端自定义Cookie实现实例 几乎所有脚本语言都提供了方便的 HTTP 客户端处理的功能,Python 也不例外,使用 urllib 和 urllib2 可以很方便地进行 HTTP GET 和 POST

  • 问题内容: 我正在与socket.io聊天应用程序,我想用我的自定义客户端ID,而不是默认的(,)。连接时是否有任何发送自定义标识符的方式,或仅使用某种方式来跟踪每个ID的自定义名称?谢谢! 问题答案: 您可以在服务器上创建一个数组,并在其上存储自定义对象。例如,您可以存储Socket.io创建的ID和每个客户端发送到服务器的自定义ID: 在此示例中,您需要从每个客户端调用 storeClient

  • 我有一个用于其他服务的外部http客户端,我已经将其导入到我的micronaut应用程序中,但收到一个错误,该错误指出: 原因:io.Micronaut.Context.Exceptions.NoSuchBeanException:不存在类型为[xxx.files.client.Micronaut.filesclient]的bean。确保bean没有被bean要求禁用(为'io.micronaut

  • 问题内容: 如何使HTTPClient使用自定义User-Agent标头? 以下代码提交空的用户代理。我想念什么? 问题答案: 线 不见了。添加并享受。

  • 我过去成功地使用过Akka Streams,但是,我现在很难理解为什么Akka HTTP中定义了客户端Websocket流,并按照文档中显示的方式工作。 由于WebSocket连接允许全双工通信,我希望这样的连接在Akka HTTP中由两个独立的流表示,一个用于传入流量,一个用于传出流量。事实上,文件说明了以下内容: WebSocket由两个消息流组成[…] 它还指出,传入消息由表示,传出消息由表