javascript
Spring Cloud OpenFeign使用教程
文章目錄
- Spring Cloud OpenFeign Demo
 - 怎么配置OpenFeignServer
 - 怎么配置OpenFeignClient
 - 多個參數傳遞問題
 - FeignClient的日志問題
 - 多個FeignClient使用同一個name的問題
 - 如何運行
 
Spring Cloud OpenFeign Demo
之前項目中需要在Spring Cloud中使用OpenFeign的情況,Spring Cloud的版本是目前最新的Greenwich.SR2版本,對應的Spring boot是2.1.7.RELEASE。
在網上找了很多資料,大多言之不詳,并且版本也比較低,不適合我的最新版本Spring Cloud的需求。 所以決定還是自己寫個教程。
本教程要解決如下幾個問題:
怎么配置OpenFeignServer
我們知道OpenFeign是用在Spring Cloud中的聲明式的web service client。
OpenFeignServer就是一個普通的Rest服務,不同的是我們需要將他注冊到eureka server上面,方便后面的OpenFeignClient調用。
啟動類如下:
@SpringBootApplication @EnableDiscoveryClient public class OpenFeignServer {public static void main(String[] args) {SpringApplication.run(OpenFeignServer.class, args);} }我們定義了兩個Rest服務:
OrderController:
@Slf4j @RestController @RequestMapping(path = "/order") public class OrderController {/*** PostMapping with @RequestBody* @param user*/@PostMapping("doOrder")public void doOrder(@RequestBody User user){log.info("do order !!!!");} }UserController:
@RestController @RequestMapping(path = "/user") public class UserController {/*** GetMapping example with @RequestParam* @param userId* @return userName*/@GetMapping("getUserName")public String getUserName(@RequestParam("userId") String userId){if("100".equals(userId)) {return "張學友";}else{return "劉德華";}}/*** GetMapping example with @RequestParam and @SpringQueryMap* @param userId* @param user* @return userAge*/@GetMapping("getUserAge")public String getUserAge(@RequestParam("userId") String userId, @SpringQueryMap User user){if("100".equals(userId)) {return "20";}else{return "18";}} }我們將其注冊到eureka上面,名字為openfeign-server
spring:application:name: openfeign-server怎么配置OpenFeignClient
OpenFeignClient的pom依賴如下:
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>配置OpenFeignClient只需要使用@FeignClient來注解一個interface即可,如下所示:
@FeignClient(value = "openfeign-server") @RequestMapping(path = "/user") public interface UserClient {@GetMapping("getUserName")public String getUserName(@RequestParam("userId") String userId);@GetMapping("getUserAge")public String getUserAge(@RequestParam("userId") String userId, @SpringQueryMap User user); }其中@FeignClient中的value是要調用的服務的注冊名,即OpenFeignServer在eureka的注冊名。
FeignClient的 Request路徑,方式和參數要和被調用的Rest服務保持一致。
這樣我們就可以像下面一樣來調用OpenFeignClient了:
@Slf4j @RestController public class UserController {@Autowiredprivate UserClient userClient;@GetMapping("getUserName2")public void getUserName(){log.info(userClient.getUserName("100"));} }多個參數傳遞問題
一般我們會使用@GetMapping和@PostMapping兩種方式來調用Rest服務。
而接收的參數則會使用@RequestParam和@RequestBody來獲取。
首先我們講一下@RequestBody,@RequestBody只能用在Post請求,并且一個Post請求只能有一個@RequestBody。 @RequestBody的參數可以包括復雜類型。
然后我們講一下@RequestParam,@RequestParam可以用在Post和Get請求中,但是要注意:@RequestParam 的參數只能是基本類型或者Enum,或者List和Map(List和Map里面也只能是基本類型)。所以@RequestParam可以和@RequestBody一起使用。
如果我們是Get請求,但是又有復合類型怎么辦? 比如我們想傳遞一個User對象。User對象里面只有普通的兩個String屬性。 這里我們可以使用@SpringQueryMap:
@GetMapping("getUserAge")public String getUserAge(@RequestParam("userId") String userId, @SpringQueryMap User user);注意:@SpringQueryMap后面的參數只能是普通的POJO,不能是復合類型,否則解析不了。如果必須使用復合類型,那么使用@RequestBody吧。
FeignClient的日志問題
OpenFeign的Logger.Level有4種級別:
- NONE 沒有日志
 - BASIC 請求方法,請求URL,返回Code和執行時間
 - HEADERS 請求和返回的頭部基本信息
 - FULL 請求和返回的頭部,內容,元數據
 
要想使用這些級別,必須將OpenFeignClient的logger設置成debug級別:
#日志配置 logging:level:com:flydean: debug同時我們在代碼中配置OpenFeign的日志級別:
@Configuration public class CustFeignLogConfig {@BeanLogger.Level feignLoggerLevel() {return Logger.Level.FULL;} }這樣我們在日志里面就可以看到DEBUG的所有HTTP請求信息。
多個FeignClient使用同一個name的問題
其實這里我們的Server定義了兩個Rest服務,User和Order。
上面我們講到了可以這樣定義UserClient:
@FeignClient(value = "openfeign-server") @RequestMapping(path = "/user") public interface UserClient {... }如果我們同樣的這樣定義OrderClient:
@FeignClient(value = "openfeign-server") @RequestMapping(path = "/order") public interface OrderClient {... }運行時候就會報錯。 原因是兩個FeignClient使用了同一個value!
那怎么解決這個問題呢?
/*** 因為@FeignClient的value不能重復,所以需要在這里以自定義的方式來創建* @author wayne* @version FeignClientController, 2019/9/5 7:07 下午*/ @Data @Component @Import(FeignClientsConfiguration.class) public class FeignClientController {private OrderClient orderClient;private UserClient userClient;public FeignClientController(Decoder decoder, Encoder encoder, Client client, Contract contract) {this.orderClient = Feign.builder().client(client).encoder(encoder).decoder(decoder).contract(contract)//默認是Logger.NoOpLogger.logger(new Slf4jLogger(OrderClient.class))//默認是Logger.Level.NONE.logLevel(Logger.Level.FULL).target(OrderClient.class, "http://openfeign-server");this.userClient = Feign.builder().client(client).encoder(encoder).decoder(decoder).contract(contract)//默認是Logger.NoOpLogger.logger(new Slf4jLogger(UserClient.class))//默認是Logger.Level.NONE.logLevel(Logger.Level.FULL).target(UserClient.class, "http://openfeign-server");} }方法就是手動創建FeignClient, 上面的例子中,我們手動創建了OrderClient和UserClient兩個FeignClient。
注意下面的代碼片段,手動創建的FeignClient默認是沒有logger和logLevel的。所以上面我們配置好的log信息對手動創建的FeignClient是無效的。 下面展示了如何手動添加:
//默認是Logger.NoOpLogger.logger(new Slf4jLogger(OrderClient.class))//默認是Logger.Level.NONE.logLevel(Logger.Level.FULL)如何運行
本項目的模塊都是以spring boot構建的,直接在編譯器中運行Main方法即可啟動。
openfeign-registry-server會啟動eureka server,供后面的OpenFeignServer和OpenFeignClient注冊。
啟動openfeign-server
啟動openfeign-client
測試openFeignClient
get請求url: http://localhost:8000/getUserName1
查看日志,看看輸出吧。
本項目代碼地址 :spring-cloud-openfeign-demo
更多精彩內容且看:
- 區塊鏈從入門到放棄系列教程-涵蓋密碼學,超級賬本,以太坊,Libra,比特幣等持續更新
 - Spring Boot 2.X系列教程:七天從無到有掌握Spring Boot-持續更新
 - Spring 5.X系列教程:滿足你對Spring5的一切想象-持續更新
 - java程序員從小工到專家成神之路(2020版)-持續更新中,附詳細文章教程
 
更多教程請參考 flydean的博客
總結
以上是生活随笔為你收集整理的Spring Cloud OpenFeign使用教程的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 公钥私钥
 - 下一篇: Spring Cloud sleuth