springcloud之Feign的使用

首先引用spring官网对Feign的解析:

Feign is a declarative web service client. It makes writing web service clients easier. To use Feign create an interface and annotate it. It has pluggable annotation support including Feign annotations and JAX-RS annotations. Feign also supports pluggable encoders and decoders. Spring Cloud adds support for Spring MVC annotations and for using the same HttpMessageConverters used by default in Spring Web. Spring Cloud integrates Ribbon and Eureka to provide a load balanced http client when using Feign. 

 Feign是一个声明性的HTTP服务客户端。它使编写web服务客户端变得更容易。使用Feign创建一个接口并注释它。它具有可插拔的注释支持,包括Feign注解和JAX-RS注释。另外,对于Feign自身的一些主要组件,比如编码器和解码器等,它也以可插拔的方式提供。。Spring Cloud集成了Ribbon和Eureka ,在使用Feign时,它提供了一个负载均衡的http客户端。

我们可以使用RestTemplate的请求拦截来实现对依赖服务的接口调用,他已经实现了对HTTP请求的封装处理,形成了模块化的嗲用方法,Spring-Cloud Feign在此基础上做了进一步封装,我们只需要创建一个接口并用注解方式来配置它,就可以对服务提供方进行接口绑定,简化了在使用spring-cloud ribbon时候自行封装客户端调用的开发量。

如何使用Feign呢?

1、引入依赖:

<dependency>
    <groudId>org.springframework.cloud</groudId>
    <artifactId>spring-cloud-starter-feign<artifactId>
</dependency>

2、在启动类添加Feign启动注解(@EnableFeignClients

@Configuration
@ComponentScan
@EnableAutoConfiguration
@EnableEurekaClient
@EnableFeignClients
public class Application {

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

}

3、定义HelloUserService接口,通过@FeignClient注解指定服务名来绑定服务,然后再使用spring MVC的注解来绑定具体服务提供的REST接口。

@FeignClient("hello-users")
public interface HelloUserService{

    @RequestMapping(method = RequestMethod.GET, value = "/getUsers")
    List<User> getUsers();

}

4、创建一个UserController来实现对Feign客户端的调用,使用@Autowired直接注入上面的HelloUserService实例,并在getUsers函数中调用这个绑定了hello-users服务接口的客户端来向该服务发起"/getUsers"接口的调用。

@RestController
public class UserController{

  @Autowired
  private HelloUserService helloUserService ;

  @GetMapping("/getUsers")
  public List<User> getUsers() {
    return this.helloUserService .getUsers();
  }
}

5、需要在application.yml中指定服务注册中心,并定义自身的服务名为feign-demo,指定端口等。至此,整个简单的Feign demo就大概完成了。

下面解析一下Feign常见的各种坑:

1、 @RequestMapping(value = "/user", method = RequestMethod.GET)
  public User findUserById(@RequestParam Long userId  );

Caused by:java.lang.IllegalStateException: RequestParam .value() was empty on parameter 0”

解决方案:是@RequestParam(“userId”) Long userId   中的扩号里面的参数名忘记写了.

2、 @GetMapping(value = "/simple/{id}")
  public User findById(@PathVariable("id") Long id);

Caused by: java.lang.IllegalStateException: Method findById not annotated with HTTP method type (ex. GET, POST)

解决方案:Feign不支持@GetMapping注解。只能乖乖使用@RequestMapping。

3、 @RequestMapping(value = "/simple/{id}", method = {RequestMethod.GET,RequestMethod.POST})
  public User findOneById(@PathVariable("id") Long id);

Caused by: java.lang.IllegalStateException: Method findById can only contain 1 method field. Found: [GET, POST]

 解决方案:Feign只可以在GET,POST调用方式中选择其中一种。

4、 @RequestMapping(value = "/test-get-user", method = RequestMethod.GET)
  public User getUser(User user);

feign.FeignException: status 405 reading HelloUserService#getUser(User); content:
{"timestamp":1534068287452,"status":405,"error":"Method Not Allowed","exception":"org.springframework.web.HttpRequestMethodNotSupportedException","message":"Request method 'POST' not supported","path":"/test-get-user"

解决方法: 该请求不会成功,只要参数是复杂对象,即使指定了是GET方法,feign依然会以POST方法进行发送请求。如果服务方非要使用GET方法,只能把客户端一个一个参数的来对应写上了,例如此方法中 getUser(@RequestParam("id") Long id,@RequestParam("name") String name,@RequestParam("age") int age);

持续更新中......

猜你喜欢

转载自blog.csdn.net/liangweihua123/article/details/81538251