Feign快速入門

Ruthless發表於2018-12-27

一、Feign簡介
1、Feign是一個宣告式的web服務客戶端,使用Feign編寫web服務客戶端更加容易
2、具有可插拔註解支援,包括Feign註解和JAX-RS註解,還支援可插拔的編碼器與解碼器
3、Spring Cloud 增加了對 Spring MVC的註解的支援,Spring Web 預設使用了HttpMessageConverters
4、Spring Cloud 整合了 Ribbon 和 Eureka,在使用Feign時提供負載均衡的HTTP客戶端

二、匯入依賴

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

三、開啟註解

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients //開啟Feign支援
public class ConsumerApplication {

}

 

四、Feign入門示例
1、ProducerController——服務提供者,在mima-cloud-producer專案中

@RestController
public class ProducerController {
    
    @GetMapping("/get/{id}")
    public String get(@PathVariable String id) {
        return "hi,"+id;
    }
    
    @GetMapping("/getuser/{id}")
    public User getUser(@PathVariable String id) {
        System.out.println("getUser.....");
        User user = new User();
        user.setId(id);
        user.setName("wangwu" + id);
        return user;
    }
    
    @PostMapping("/postuser")
    public User postUser(@RequestBody User user) {
        System.out.println("postUser.....");
        return user;
    }
    
    @GetMapping("/getuser2")
    public User getUser2(User user) {
        System.out.println("getUser2.....");
        return user;
    }
    
    @GetMapping("/listAll")
    public List<User> listAll(){
        List<User> users = new ArrayList<User>();
        users.add(new User("1","kevin1"));
        users.add(new User("2","kevin2"));
        users.add(new User("3","kevin3"));
        return users;
    }
}

 

以下程式碼在cloud-consumer-feign專案中
2、FeignTestClient——定義Feign客戶端,宣告式介面與ProducerController服務提供的方法一一對應

//定義Feign客戶端,value引數為provider的serviceName。name引數實際是value的別名
//@FeignClient("mima-cloud-producer")與@FeignClient(name="mima-cloud-producer")本質相同
//@FeignClient(url="")引數已經作廢,必須使用name屬性
//如果設定url屬性, 則name屬性則只代表Feign客戶端的別名,而不代表服務端的serviceName
@FeignClient(name="mima-cloud-producer")
public interface FeignTestClient {

    // 可以使用GetMapping組合註解,以前是不能使用的
    @GetMapping(value = "/get/{id}")
    // @PathVariable必須指定value,否則異常:PathVariable annotation was empty on param 0.
    public String get(@PathVariable("id") String id);

    @RequestMapping(value = "/getuser/{id}")
    public User getUser(@PathVariable("id") String id);
    
    // 呼叫遠端的post方法,如果引數為複雜物件,就算指定了method=RequestMethod.GET,依然會使用post方式請求
    // 遠端的方法是get的時候就會失敗,錯誤訊息: status 405 reading FeignTestClient#getUser2(User); content:{"timestamp":1511326531240,"status":405,"error":"Method Not Allowed","exception":"org.springframework.web.HttpRequestMethodNotSupportedException","message":"Request method 'POST' not supported","path":"/getuser2"}
    @RequestMapping(value = "/getuser2", method = RequestMethod.GET)
    public User getUser2(User user);

    // 呼叫遠端的post方法,可以使用@RequestBody
    @RequestMapping(value = "/postuser")
    public User postUser(@RequestBody User user);

    // 呼叫遠端的post方法,可以不使用@RequestBody
    @RequestMapping(value = "/postuser")
    public User postUser2(User user);

    // 呼叫遠端的post方法,如果引數為複雜物件,就算指定了method=RequestMethod.GET,依然會使用post方式請求
    // 遠端的方法也是post的,所以可以呼叫成功
    @RequestMapping(value = "/postuser", method = RequestMethod.GET)
    public User postUser3(User user);

    @GetMapping(value = "/listAll")
    List<User> listAll();
}

 

3、FeignTestController——呼叫Feign客戶端

@RestController
public class FeignTestController {
    
    @Autowired
    private FeignTestClient feignTestClient;
    
    @GetMapping("/feign/get/{id}")
    public String get(@PathVariable String id) {
        String result = feignTestClient.get(id);
        return result;
    }
    
    @GetMapping("/feign/getuser/{id}")
    public User getUser(@PathVariable String id) {
        User result = feignTestClient.getUser(id);
        return result;
    }
    
    @GetMapping("/feign/getuser2")
    public User getUser2(User user) {
        User result = feignTestClient.getUser2(new User());
        return result;
    }
    
    @GetMapping("/feign/listAll")
    public List<User> listAll() {
        return feignTestClient.listAll();
    }
    
    @PostMapping("/feign/postuser")
    public User postUser(@RequestBody User user) {
        User result = feignTestClient.postUser(user);
        return result;
    }
    
    @PostMapping("/feign/postuser2")
    public User postUser2(@RequestBody User user) {
        User result = feignTestClient.postUser2(user);
        return result;
    }
    
    @PostMapping("/feign/postuser3")
    public User postUser3(@RequestBody User user) {
        User result = feignTestClient.postUser3(user);
        return result;
    }
    
}

 

4、開啟Feign註解

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients //開啟Feign支援
public class ConsumerApplication {
    
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
    
}