Feign-1 Feign的简介及基础使用
生活随笔
收集整理的這篇文章主要介紹了
Feign-1 Feign的简介及基础使用
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
討論聲明式的REST Client Feign7. Declarative REST Client: Feignhttps://cloud.spring.io/spring-cloud-netflix/multi/multi_spring-cloud-feign.html首先我們來看一下Feign是什么,Feign是一個聲明式的web service的客戶端,他讓寫web service的客戶端更加的容易,如果你想用Feign創(chuàng)建一個接口,然后添加一些注解,就OK了,他說他支持Feign的注解,JAX-RS的注解,大家知道JAX-RS是什么嗎,JAX-RS是JAVA API For RESTFul Service,說到JAX-RS就不得不說到另一個標(biāo)準(zhǔn),它是一個WEB Service的標(biāo)準(zhǔn),JAX-WS,JAVA API For Web Service,這個大家可能都看過,就是之前的SOAP協(xié)議,WEB Service里面的一堆標(biāo)準(zhǔn),有了REST出來了,JAVA與時俱進(jìn),他又搞了一個REST Service的一個標(biāo)準(zhǔn),它是一個標(biāo)準(zhǔn),如果大家想深入了解JAX-RS的話,你用這樣的一個框架進(jìn)行入門,叫jersey,JAX-RS的話,其實有一部分是參考了jersey的設(shè)計,當(dāng)然cxf,他也是支持JAX-RS標(biāo)準(zhǔn)的,Feign同樣支持,可插拔的編碼器和解碼器,Spring Cloud為Feign添加了SpringMVC的注解,使用相同的HttpMessageConverters,我們知道SpringMVC的Converter,說白了Spring Cloud擴展了Feign,支持了SpringMVC的注解,在Spring Cloud使用Feign的時候,他整合了Ribbon和Eureka,以提供負(fù)載均衡的能力,首先他是一個聲明式的HTTP的client,如果你想使用它的話,創(chuàng)建一個接口,然后添加注解,最后他還整合了Ribbon和Eureka,他還可以使用SpringMVC的注解,降低了我們的學(xué)習(xí)成本,否則不管我們要學(xué)Feign的注解,我們其實都是有額外的學(xué)習(xí)成本的,我們來看一下Feign的githubFeign 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.https://github.com/OpenFeign/feign它的URL最近發(fā)生了變化,其實他是netflix的產(chǎn)品,他被重定向到OpenFeign/feign,我們來看一下Feign的版本,https://github.com/OpenFeign/feign/releases它的版本迭代的非常的快,它的代碼更新也是非常的頻繁,這個東西很活躍,很有前途的,怎么樣使用這個Feign呢,7.1 How to Include Feign光知道這個東西介紹的再好有什么用啊,我們怎么樣用,在Spring Cloud或者SpringBoot里面,基本上會有一個思維定式了,引入他的starterTo include Feign in your project use the starter with group org.springframework.cloud and artifact id spring-cloud-starter-openfeign. See the Spring Cloud Project page for details on setting up your build system with the current Spring Cloud Release Train.Example spring boot app@SpringBootApplication
@EnableFeignClients
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}}我們在啟動類上加上@EnableFeignClients這個注解StoreClient.java. @FeignClient("stores")
public interface StoreClient {@RequestMapping(method = RequestMethod.GET, value = "/stores")List<Store> getStores();@RequestMapping(method = RequestMethod.POST, value = "/stores/{storeId}", consumes = "application/json")Store update(@PathVariable("storeId") Long storeId, Store store);
}這才是正題,創(chuàng)建一個接口,在接口上添加一個注解localhost:8010/movie/1timeout解釋一下,可能是應(yīng)用剛啟動,因為它會從Eureka上拉,拉東西,它會把虛擬IP@FeignClient("microservice-simple-provider-user")轉(zhuǎn)成真正的IP,所以他可能會造成一個超時,localhost:8010/test/?id=1&username=zhangsan&age=20{"id":1,"username":"zhangsan","name":null,"age":20,"balance":null}localhost:7900/get-user/?id=1&username=zhangsan&age=20localhost:8010/test-get/?id=1&username=zhangsan&age=20feign.FeignException: status 405 reading UserFeignClient#getUser(User); content:{"timestamp":1566720796075,"status":405,"error":"Method Not Allowed","exception":"org.springframework.web.HttpRequestMethodNotSupportedException","message":"Request method 'POST' not supported","path":"/get-user"
}你請求的方法是POST,// 該請求不會成功,只要參數(shù)是復(fù)雜對象,即使指定了是GET方法,feign依然會以POST方法進(jìn)行發(fā)送請求。
// 可能是我沒找到相應(yīng)的注解或使用方法錯誤。
@RequestMapping(value = "/get-user", method = RequestMethod.GET)
public User getUser(User user);
package com.learn.cloud.entity;import java.math.BigDecimal;public class User {public User(Long id, String name) {super();this.id = id;this.name = name;}public User() {super();}private Long id;private String username;private String name;private Short age;private BigDecimal balance;public Long getId() {return this.id;}public void setId(Long id) {this.id = id;}public String getUsername() {return this.username;}public void setUsername(String username) {this.username = username;}public String getName() {return this.name;}public void setName(String name) {this.name = name;}public Short getAge() {return this.age;}public void setAge(Short age) {this.age = age;}public BigDecimal getBalance() {return this.balance;}public void setBalance(BigDecimal balance) {this.balance = balance;}
}
package com.learn.cloud.controller;import java.util.ArrayList;
import java.util.List;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;import com.google.common.collect.Lists;
import com.learn.cloud.entity.User;
import com.learn.cloud.mapper.UserMapper;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.EurekaClient;@RestController
public class UserController {@Autowiredprivate UserMapper userMapper;@Autowiredprivate EurekaClient eurekaClient;@Autowiredprivate DiscoveryClient discoveryClient;@GetMapping("/simple/{id}")public User findById(@PathVariable Long id) {return this.userMapper.getUserById(id);}@GetMapping("/eureka-instance")public String serviceUrl() {InstanceInfo instance = this.eurekaClient.getNextServerFromEureka("MICROSERVICE-SIMPLE-PROVIDER-USER", false);return instance.getHomePageUrl();}@GetMapping("/instance-info")public ServiceInstance showInfo() {ServiceInstance localServiceInstance = this.discoveryClient.getLocalServiceInstance();return localServiceInstance;}@PostMapping("/user")public User postUser(@RequestBody User user) {return user;}// 該請求不會成功@GetMapping("/get-user")public User getUser(User user) {return user;}@GetMapping("list-all")public List<User> listAll() {ArrayList<User> list = Lists.newArrayList();User user = new User(1L, "zhangsan");User user2 = new User(2L, "zhangsan");User user3 = new User(3L, "zhangsan");list.add(user);list.add(user2);list.add(user3);return list;}
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><artifactId>microservice-consumer-movie-feign</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>microservice-simple-consumer-movie</name><description>Demo project for Spring Boot</description><parent><groupId>cn.learn</groupId><artifactId>microcloud02</artifactId><version>0.0.1</version></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-feign</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
#debug=true
server.port=8010eureka.client.serviceUrl.defaultZone=http://admin:1234@10.40.8.152:8761/eurekaspring.application.name=microservice-consumer-movie-ribbon
eureka.instance.prefer-ip-address=true
eureka.instance.instance-id=${spring.application.name}:${spring.cloud.client.ipAddress}:${spring.application.instance_id:${server.port}}
eureka.client.healthcheck.enabled=true
spring.redis.host=10.40.8.152
spring.redis.password=1234
spring.redis.port=6379#stores.ribbon.listOfServers=10.40.8.144:7900
package com.learn.cloud.feign;import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;import com.learn.cloud.entity.User;@FeignClient("microservice-simple-provider-user")
public interface UserFeignClient {@RequestMapping(value = "/simple/{id}", method = RequestMethod.GET)// 兩個坑:1. @GetMapping不支持 2. @PathVariable得設(shè)置valuepublic User findById(@PathVariable("id") Long id); @RequestMapping(value = "/user", method = RequestMethod.POST)public User postUser(@RequestBody User user);// 該請求不會成功,只要參數(shù)是復(fù)雜對象,即使指定了是GET方法,feign依然會以POST方法進(jìn)行發(fā)送請求。可能是我沒找到相應(yīng)的注解或使用方法錯誤。@RequestMapping(value = "/get-user", method = RequestMethod.GET)public User getUser(User user);}
package com.learn.cloud.controller;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;import com.learn.cloud.entity.User;
import com.learn.cloud.feign.UserFeignClient;@RestController
public class MovieController {@Autowiredprivate UserFeignClient userFeignClient;@GetMapping("/movie/{id}")public User findById(@PathVariable Long id) {return this.userFeignClient.findById(id);}@GetMapping("/test")public User testPost(User user) {return this.userFeignClient.postUser(user);}@GetMapping("/test-get")public User testGet(User user) {return this.userFeignClient.getUser(user);}
}
package com.learn.cloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class ConsumerMovieFeignApplication {public static void main(String[] args) {SpringApplication.run(ConsumerMovieFeignApplication.class, args);}
}
?
總結(jié)
以上是生活随笔為你收集整理的Feign-1 Feign的简介及基础使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ribbon-4 Ribbon脱离Eur
- 下一篇: Feign-2覆写Feign的默认配置