文章目录
- [OpenFeign 参数传递](#OpenFeign 参数传递)
- 最佳实践
OpenFeign 参数传递
通过观察,我们也可以发现,Feign 的客户端和服务提供者的接口非常相似。上面例子中,演示了 Feign 从 URL 中获取参数,接下来演示 Feign 参数传递的其他方法
- 只做代码演示,不做功能
传递单个参数
服务提供方:product-service
java
@RequestMapping("/product")
@RestController
public class ProductController {
@RequestMapping("/p1")
public String p1(Integer id){
return "p1 接收到参数:" + id;
}
}
Feign 客户端
java
@FeignClient(value = "product-service", path = "/product")
public interface ProductApi {
@RequestMapping("/p1")
String p1(@RequestParam("id") Integer id);
}
@RequestParam做参数绑定,不能省略
服务消费方:order-service
java
@RequestMapping("/feign")
@RestController
public class TestFeignController {
@Autowired
private ProductApi productApi;
@RequestMapping("/o1")
public String o1(Integer id) {
return productApi.p1(id);
}
}
测试远程调用: http://127.0.0.1:8080/feign/o1?id=5

传递多个参数
使用多个 @RequestParam 进行参数绑定即可
服务提供方 product-service
java
@RequestMapping("/p2")
public String p2(Integer id, String name) {
return "p2 接受到参数,id:" + id + ", name: " + name;
}
Feign 客户端
java
@RequestMapping("/p2")
String p2(@RequestParam("id") Integer id, @RequestParam("name") String name);
服务消费方 order-service
java
@RequestMapping("/o2")
public String o2(Integer id, String name) {
return productApi.p2(id, name);
}
测试远程调用: http://127.0.0.1:8080/feign/o2?id=5\&name=zhangsan

传递对象
服务提供方 product-service
java
@RequestMapping("/p3")
public String p3(ProductInfo productInfo) {
return "接收到对象,productInfo:" + productInfo;
}
Feign 客户端
java
@RequestMapping("/p3")
String p3(@SpringQueryMap ProductInfo productInfo);
服务消费方 order-service
java
@RequestMapping("/o3")
public String o3(ProductInfo productInfo) {
return productApi.p3(productInfo);
}
测试远程调用: http://127.0.0.1:8080/feign/o3?id=5\&productName=zhangsan

传递 JSON
服务提供方 product-service
java
@RequestMapping("/p4")
public String p4(@RequestBody ProductInfo productInfo) {
return "接收到对象,productInfo: " + productInfo;
}
Feign 客户端
java
@RequestMapping("/p4")
String p4(@RequestBody ProductInfo productInfo);
}
服务消费方 order-service
java
@RequestMapping("/o4")
public String o4(@RequestBody ProductInfo productInfo) {
System.out.println(productInfo.toString());
return productApi.p4(productInfo);
}
测试远程调用: http://127.0.0.1:8080/feign/o4

最佳实践
最佳实践,其实也就是经过历史的迭代,在项目中的事件过程中,总结出来的最好的使用方式
通过观察,我们也能看出来,Feign 的客户端与服务提供者的 controller 代码非常相似
Feign客户端
java
@FeignClient(value = "product-service", path = "/product")
public interface ProductApi {
@RequestMapping("/{productId}")
ProductInfo getProductById(@PathVariable("productId") Integer productId);
}
- 服务提供方
controller
java
@RequestMapping("/product")
@RestController
public class ProductController {
@RequestMapping("/{productId}")
public ProductInfo getProductById(@PathVariable("productId") Integer productId) {
//...
}
有没有一种方法可以简化这种写法呢
Feign 继承方式
Feign 支持继承的方式,我们可以把一些常见的操作封装到接口里
我们可以定义好一个接口,服务提供方实现这个接口,服务消费方编写 Feign 接口的时候,直接继承这个接口
创建一个 Module
接口可以放在一个公共的 Jar 包里,供服务提供方和服务消费方使用

引入依赖
xml
<dependencies>
<!-- Spring Boot Web Starter for web capabilities -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Cloud OpenFeign for declarative REST client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
编写接口
复制 ProductApi,ProductInfo 到 product-api 模块中
java
package org.example;
import org.example.model.ProductInfo;
import org.springframework.cloud.openfeign.SpringQueryMap;
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.RequestParam;
public interface ProductInterface {
@RequestMapping("/{productId}")
ProductInfo getProductById(@PathVariable("productId") Integer productId);
@RequestMapping("/p1")
String p1(@RequestParam("id") Integer id);
@RequestMapping("/p2")
String p2(@RequestParam("id") Integer id, @RequestParam("name") String name);
@RequestMapping("/p3")
String p3(@SpringQueryMap ProductInfo productInfo);
@RequestMapping("/p4")
String p4(@RequestBody ProductInfo productInfo);
}
目录结构为: