标签: feign

SpringBoot:带 SSL 的 FeignClient (p12)

我正在尝试为一个使用 SSL 的外部 HTTP API 创建一个 FeignClient。斗争是 - 如何用我的逻辑修改默认的 Spring FeignClient,在这种情况下是 SSL 连接工厂。所以基本上我想保留 Spring 自动为 FeignClients 做的所有好事,比如 Hystrix、Sleuth 跟踪等,并让它与我的 SSL 工厂一起工作。

将不胜感激任何建议。


这是我尝试做的:

我尝试在 ComponentScan 之外提供自定义 @Configuration:

@Configuration
public class CustomFeignConfiguration
{
    @Bean
    public Feign.Builder feignBuilder()
    {
        Client trustSSLSockets = new Client.Default(
                TrustingSSLSocketFactory.get("server1"),
                new NoopHostnameVerifier());

        log.info("feignBuilder called");
        return Feign.builder().client(trustSSLSockets);
    }
...
}
Run Code Online (Sandbox Code Playgroud)

通过注解让 FeignClient 使用

    @FeignClient(name = "sslClient", configuration = CustomFeignConfiguration.class, url = "https://...")
Run Code Online (Sandbox Code Playgroud)

其中“TrustingSSLSocketFactory”的实现与此类似。

现在,如果我在 Spring 应用程序中注入我的客户端,我可以看到“feignBuilder”被调用并且它成功加载了我的密钥。问题是创建的客户端实际上并未将指定的 SSLFactory 用于 createSocket 调用。所以我得到:

Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: …
Run Code Online (Sandbox Code Playgroud)

java ssl spring-boot spring-cloud feign

6
推荐指数
1
解决办法
1万
查看次数

春云假装hystrix后退不起作用

弹簧启动版本1.3.8.RELEASE和云版本'Brixton.SR'相同的代码工作正常.但是'1.5.2.RELEASE'和'Dalston.RC1'不起作用.

例外

HTTP状态500 - 请求处理失败; 嵌套异常是java.lang.RuntimeException:com.netflix.client.ClientException:负载均衡器没有客户端的可用服务器:math-service

java spring hystrix spring-cloud feign

6
推荐指数
1
解决办法
2801
查看次数

Feign - URL 编码路径参数

这是我的契约

@RequestLine("GET /products/{id}")
@Headers({"Content-Type: application/json"})
ApiResponse getProduct(@Param("id") String productId) throws Exception;
Run Code Online (Sandbox Code Playgroud)

我想获取 id = "a/b" 的产品,

如果我将此作为参数发送给 getProduct("a/b")

然后形成的 URL 是http://api/products/a/b404,而不是 URL 应该是http://api/products/a%2Fb

有没有解决的办法?

spring-boot netflix-feign feign

6
推荐指数
1
解决办法
1万
查看次数

Java - SpringBoot + Feign + Eureka(Feign不解析来自Eureka的URL)

我已经有一个 Eureka 服务器正在运行,并且在那里注册了一个微服务(account-server -> Service B)。问题是当尝试使用Service A中的 Feign 时。假设我在服务 A 上了一堂课。

@FeignClient("account-server")
public interface AccountFooProxy {
    @RequestMapping(
            value = {"/deviceToken/{deviceToken}"},
            method = {RequestMethod.GET}
    )
    String getAccountByDeviceToken(@PathVariable("deviceToken") String var1);

}
Run Code Online (Sandbox Code Playgroud)

我已经知道“帐户服务器”已在尤里卡注册。服务A中的SpringBoot是:

@SpringBootApplication
@EnableFeignClients
@EnableDiscoveryClient
public class AuthServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(AuthServerApplication.class, args);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后是同一个服务 A 中的 RestController,我在其中创建了这个虚拟类以 @Autowired 一个 FeignClient 来调用服务 B

@RestController
@RequestMapping("/foo")
class FooTest {

    @Autowired
    private AccountFooProxy accountProxy;

    private static final String DEVICE_TOKEN = "xxx";

    @RequestMapping(path = "/foo", method = …
Run Code Online (Sandbox Code Playgroud)

java spring-boot netflix-eureka feign netflix-ribbon

6
推荐指数
0
解决办法
6282
查看次数

Feign 客户端重试异常

到目前为止,我们有一个 feign 客户端,如果出现异常,我们曾经重试如下

Retryer<ClientResponse> retryer = RetryerBuilder.<ClientResponse>newBuilder()
  .retryIfExceptionOfType(FeignException.class)
  .withStopStrategy(StopStrategies.stopAfterAttempt(retryCount))
  .withWaitStrategy(WaitStrategies.exponentialWait(maxWaitSeconds, TimeUnit.SECONDS))
  .build();
    
retryer.call(() -> { 
  return client.doStuffs(someInput); }
);
Run Code Online (Sandbox Code Playgroud)

最近我尝试从这个自定义重试器移动到一个内置的假装重试器,如下所示:

Feign client = Feign.builder()
    .decoder(jacksonDecoder)
    .encoder(jacksonEncoder)
    .logger(slf4jLogger)
    .client(okHttpClient)
    .retryer(new Retryer.Default(
                            SECONDS.toMillis(minWaitSeconds), 
                            SECONDS.toMillis(maxWaitSeconds), 
                            retryCount
            ))
    .requestInterceptor(new BasicAuthRequestInterceptor(clientConfig.getUser(), clientConfig.getPassword()))
    .target(target);
    
client.doStuffs(someInput);
Run Code Online (Sandbox Code Playgroud)

理解是假装客户端本身会处理异常,但显然,情况并非如此,当客户端抛出 a 时5xx,我得到一个异常而没有重试。实现重试是否还需要其他东西?

这项服务在 dropwizard 中,git 和 SO 线程主要围绕 spring/ribbon 而我不是这种情况。

深度

<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-core</artifactId>
    <version>${feign.version}</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

java dropwizard feign openfeign

6
推荐指数
1
解决办法
1万
查看次数

Spring feign 客户端中@QueryParam 名称中的特殊字符

我们的一个外部 API 使用带有特殊字符的查询参数名称(不要问我为什么,我不知道)。我的这个 API 的假客户端方法声明如下:

@GetMapping("/v1/user/{userId}/orders")
List<Order> getOrders(
    @PathVariable("userId") String userId,
    @RequestParam("page[number]") Integer pageNumber,
    @RequestParam("page[size]") Integer pageSize);
Run Code Online (Sandbox Code Playgroud)

正如我提到的,请求参数包含特殊字符[和]. 我正在使用 Spock 进行测试,我想像这样设置 Wiremock 存根:

wiremock.stubFor(
  get(urlPathMatching('/v1/users/' + userId + '/orders'))
    .withQueryParam("page[number]", new EqualToPattern("1"))
    .withQueryParam("page[size]", new AnythingPattern())
    .willReturn(
      status(200)
        .withHeader("Content-type", "application/json")
        .withBody("""[]""")
    ))
Run Code Online (Sandbox Code Playgroud)

但我得到:

--------------------------------------------------------------------------------------------------
| Closest stub                        | Request                                                  |
--------------------------------------------------------------------------------------------------
                                      |
GET                                   | GET
/v1/users/123/orders                  | /v1/users/123/orders?page%5Bnumber%5D=%7Bpage%5Bnumber%5
                                      | D%7D&page%5Bsize%5D=%7Bpage%5Bsize%5D%7D
                                      |
Query: page[number] = 1               |                                 <<<<< Query is not present
Query: page[size] [anything] (always) |                                 <<<<< …
Run Code Online (Sandbox Code Playgroud)

spring query-parameters wiremock feign

6
推荐指数
1
解决办法
2554
查看次数

spring-cloud-starter-openfeign:无效的 HTTP 方法:PATCH 执行 PATCH

语境

我有一个 spring boot (version 2.2.6.RELEASE) web 项目。

从这个 Web 应用程序(我称之为“APP1”)我想使用来自另一个 Web 应用程序的 PATCH 方法调用另一个 URI(我们称之为“APP2”)。在我的 pom.xml 中,我有以下依赖项:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
Run Code Online (Sandbox Code Playgroud)

下面是我如何调用其他 Web 应用程序的 PATCH 方法。

@FeignClient(name = "clientName", url = "base-uri")
public interface MyInterface{
   @PatchMapping(value = "/target-uri")
    void callClientMethod(Map<String, Object> args);
Run Code Online (Sandbox Code Playgroud)

问题

  • APP2 的 PATCH 方法被有效调用
  • 但随后 APP1 抛出以下错误:
    • feign.RetryableException:无效的 HTTP 方法:PATCH 正在执行 PATCH

我在互联网上寻找解决方案,并在我的 pom.xml 中添加了以下 snipet

<dependency>
    <groupId>com.netflix.feign</groupId> <!-- Also tried io.github.openfeign -->
    <artifactId>feign-httpclient</artifactId>
    <version>8.18.0</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

之后,APP2 的 PATCH 方法仍然被正确调用,但在 APP1 中我收到以下错误: java.lang.NoSuchMethodError: feign.Response.create (ILjava/lang/String;Ljava/util/Map;Lfeign/Response$Body;)假/响应;

题 …

http-patch spring-cloud-feign feign

6
推荐指数
3
解决办法
5387
查看次数

具有自定义 JSON 响应的 Feign 错误解码器

我有一个 API,它将以自定义响应消息的形式返回失败,同时仍然发送 Http 200 响应。例子:

Status: 200
Body: {
   "code":404,
   "message":"Data not found",
   "data":{},
   "status":"ERROR"
}
Run Code Online (Sandbox Code Playgroud)

我当前的 ErrorDecoder 实现:

public class ApiFeignErrorDecoder implements ErrorDecoder {

    private final Gson gson;

    public ApiFeignErrorDecoder(Gson gson) {
        this.gson = gson;
    }

    @Override
    public Exception decode(String methodKey, Response response) {

        try {
            ApiResponse apiResponse = gson.fromJson(response.body().asReader(), BaseApiResponse.class);
            ResponseStatus status = apiResponse.getStatus();
            switch (status) {
                case SUCCESS:
                    return null;
                case FAIL:
                    return new Exception("Failure message recorded");
                case ERROR:
                    return new Exception("Error message recorded");
                default:
                    return new …
Run Code Online (Sandbox Code Playgroud)

spring-boot spring-cloud-feign feign

6
推荐指数
1
解决办法
2万
查看次数

如何在 Spring Boot 中从 InputStream 创建 MultipartFile 对象

我有 2 项服务,ServiceA并且有一个名为 的 API 。现在我想从我正在使用的API 中调用这个 API ,并且这两个服务都使用 Spring Boot。ServiceBServiceBcreateDocument(@RequestParam("file") MultipartFile file)ServiceAFeignClient

我的 FeignClient 看起来像这样

@FeignClient(
    name = "serviceB",
    url = "com.serviceb.url",
    configuration = {ServiceBErrorDecoder.class},
    fallbackFactory = ServiceBFallbackFactory.class)
@Service
public interface ServiceB{

@PostMapping(value = "/documents")
    ResponseEntity createDocument(@RequestParam("file") MultipartFile file);
}
Run Code Online (Sandbox Code Playgroud)

现在,在 ServiceA 中,我想调用这个createDocumentAPI。我可以做到这一点,但问题是如何创建MultipartFile对象并传递它?我有InputStream包含一些内容的对象,但我不想创建物理文件。

服务A代码

public void processObjects(Entity entity) throws JsonProcessingException {
    SomeObject object = new SomeObject();
    //setters
    ....
    InputStream inputStream = new ByteArrayInputStream(
            Objects.requireNonNull(SerializationUtils.serialize(object)));
    InputStreamResource inputStreamResource …
Run Code Online (Sandbox Code Playgroud)

java rest multipartform-data spring-boot feign

6
推荐指数
0
解决办法
1万
查看次数

仅为一个客户端创建 Feign 配置?

我有一大堆使用共享配置的 Feign 客户端(MyFeignConfiguration.class):

@FeignClient(name = "clientA", url = "http://serviceA.com", fallbackFactory = ServiceAFallbackFactory.class, configuration = MyFeignConfiguration.class)

@FeignClient(name = "clientB", url = "http://serviceB.com", fallbackFactory = ServiceBFallbackFactory.class, configuration = MyFeignConfiguration.class)

@FeignClient(name = "clientC", url = "http://serviceC.com", fallbackFactory = ServiceCFallbackFactory.class, configuration = MyFeignConfiguration.class)
Run Code Online (Sandbox Code Playgroud)

但是,对于新客户端,我想将用于 OkHttp 的底层 Http 客户端更改为 OkHttp。在MyFeignConfiguration课堂上,我可以添加以下内容:

@Configuration
class MyFeignConfiguration {
    @Bean
    public Client getClient() {
        return OkHttpClient() // use the OkHttp client 
    }
   
    @Bean
    public ErrorDecoder getErrorDecoder() {
        //... existing configs
    }
Run Code Online (Sandbox Code Playgroud)

然而,现在所有的客户端都在使用这个OkHttp客户端。如何配置新的 feign 客户端以便只有它使用 OkHttp 客户端?另外,我仍然需要使用 …

java rest spring spring-cloud feign

6
推荐指数
1
解决办法
9941
查看次数