Spring Cloud OpenFeign

3/2/2024 spring后端
(adsbygoogle = window.adsbygoogle || []).push({});

# 简介

简化外部调用 官方文档:https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/

# 使用

依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <version>2.2.10.RELEASE</version>
</dependency>
1
2
3
4
5

启动类加注解

@SpringBootApplication
@EnableFeignClients
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}
1
2
3
4
5
6
7
8
9

业务代码

@FeignClient(name = "${feign.name}", url = "${feign.url}", configuration = FooConfiguration.class)
public interface StoreClient {
    @RequestMapping(method = RequestMethod.GET, value = "/stores")
    List<Store> getStores();

    @RequestMapping(method = RequestMethod.GET, value = "/stores")
    Page<Store> getStores(Pageable pageable);

    @RequestMapping(method = RequestMethod.POST, value = "/stores/{storeId}", consumes = "application/json")
    Store update(@PathVariable("storeId") Long storeId, Store store);

    @RequestMapping(method = RequestMethod.DELETE, value = "/stores/{storeId:\\d+}")
    void delete(@PathVariable Long storeId);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

可以配置自动获取token等

# 注意

  1. 配置类上不需要加@Configuration注解
  2. 配置url后也需要配置name
  3. 拦截器上如果添加了@Configuration注解,会全局生效,所有的feign调用都会走这个拦截器!!

# 关键类

feign.SynchronousMethodHandler

# 查看拦截器

尤其是老项目,有大量拦截器,可能会修改入参导致不能调通接口

Request targetRequest(RequestTemplate template) {  
  for (RequestInterceptor interceptor : requestInterceptors) {  
    interceptor.apply(template);  
  }  
  return target.apply(template);  
}
1
2
3
4
5
6

# 查看实际请求

断点调试

response = client.execute(request, options);
1

# 常见问题

# 找不到bean

原因:有些老项目包路径不规范,maven分模块项目报名不一致 方法如下:

  1. 指定扫码路径 @EnableFeignClients(basePackages = "com.example.clients")
  2. 指定FeignClient类 @EnableFeignClients(clients = InventoryServiceFeignClient.class)

# 收不到值

原因:java的框架属性都是首字母小写的,有些外部系统字段首字母大写就不认了 解决方法: 实体类属性上加注解@JsonProperty("Response")

# pathVariable urlencode的内容被decode

@FeignClient(name = "yourClient", url= "xxxx", configuration = YourClient.ClientConf.class)
public interface YourClient {
  class ClientConf{
     @Bean
          Contract contract(@Autowired(required = false) List<AnnotatedParameterProcessor> parameterProcessors,
                            ConversionService feignConversionService) {
              if (parameterProcessors == null) {
                  parameterProcessors = new ArrayList<>();
              }
              return new SpringMvcContract(parameterProcessors, feignConversionService, false);
          }
   }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14

我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=38dpnhkh4o8wo