[注意]:在接口的参数前面必须使用@RequestParam加上所调用服务接口的对应参数,否则参数无法传入,就相当于在请求的后面加上了?参数=xxx.
在这里插入图片描述

也可以把该服务的接口的统一前缀(放在类上的@RequestMapping)统一放到FeignClient注解的Path参数中.

@FeignClient(name = "product-service",path = "/product")
public interface ProductApi {
    @RequestMapping("/select")
    ProductInfo getProductInfo(@RequestParam("id")Integer id);
}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

@FeignClient注解作用在接口上,参数说明:

2.4 远程调用

修改远程调用方法

@Service
public class OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private ProductApi api;
    //设置原子类
    public OrderInfo selectOrder(Integer id){
        OrderInfo orderInfo = orderMapper.selectOrderById(id);
        //把获取到的服务URL拼接到远程调用的URL中
        Integer productId = orderInfo.getProductId();
        ProductInfo productInfo = api.getProductInfo(productId);
        orderInfo.setProductInfo(productInfo);
        return orderInfo;
    }
}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"> class="hide-preCode-box">

2.5 测试

启动服务.访问接口,测试远程调用.
在这里插入图片描述

3. OpenFeign参数传递

3.1 传递单个参数

我们上面2.4的例子就是单个参数的调用.下面我们再来举一个例子

  1. 服务提供方product-service
@RestController
@RequestMapping("/product")
public class ProductController {
    @RequestMapping("/p1")
    public String p1(Integer id){
        return "接收到参数"+id;
    }
}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
  1. FeginClient
@FeignClient(value = "product-service")
public interface ProductApi {
    @RequestMapping("/product/p1")
    String p1(@RequestParam("id") Integer id);
}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

和我们上面提到的一样,@RequestParam是用来做参数绑定的,不能省略.
3. order-service

@RequestMapping("/order")
@RestController
public class OrderController {
    @Autowired
    private ProductApi api;
    @RequestMapping("/p1")
    public String p1(Integer id){
        return api.p1(id);
    }
}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

远程测试调用:GET http://127.0.0.1:8080/order/p1?id=1
在这里插入图片描述

3.2 传递多个参数

使用多个@RequestParam进行参数绑定即可

  1. 服务提供方product-service
@RestController
@RequestMapping("/product")
public class ProductController {
    @RequestMapping("/p2")
    public String p2(Integer id1,Integer id2){
        return "接收到参数1:" + id1 + ",接收到参数2:" + id2;
    }
}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
  1. FeignClient
@FeignClient(value = "product-service")
public interface ProductApi {
    @RequestMapping("/product/p2")
    String p2(@RequestParam("id1") Integer p1,@RequestParam("id2") Integer p2);
}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
  1. 服务消费方order-service
@RequestMapping("/order")
@RestController
public class OrderController {
    @Autowired
    private ProductApi api;
    @RequestMapping("/p2")
    public String p2(Integer p1,Integer p2){
        return api.p2(p1,p2);
    }
}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

调用接口进行测试:GET http://127.0.0.1:8080/order/p2?p1=1&p2=2
在这里插入图片描述

4.3 传递对象

  1. 服务提供方product-service
@RequestMapping("/p3")
public String p3(ProductInfo productInfo){
    return "接收到对象:" + productInfo;
}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
  1. Feign
@RequestMapping("/product/p3")
String p3(@SpringQueryMap ProductInfo productInfo);
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

其中@SpringQueryMap注解表示的是:可以方便地将一个对象的属性作为请求的查询参数添加到请求的 URL中,避免了手动构建查询参数字符串(如json)的繁琐过程.
3. order-service

@RequestMapping("/p3")
public String p3(ProductInfo productInfo){
    return api.p3(productInfo);
}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

测试远程调用:GET http://127.0.0.1:8080/order/p3?id=5&productName=zhangsan
在这里插入图片描述

3.4 传递Json

和我们之前学习SpringBoot的时候一样,同样是使用@RequestBody注解进行绑定.
注意由于数据在服务之间一直是按照Json格式传递的,所以服务方,服务调用方,FeignClient的参数上都需要加上注解.

  1. 服务提供方product-service
@RequestMapping("/p4")
public String p4(@RequestBody ProductInfo productInfo){
    return "接收到对象:" + productInfo;
}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
  1. FeignClient
@RequestMapping("/product/p4")
String p4(@RequestBody ProductInfo productInfo);
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
  1. 服务消费方order-service
@RequestMapping("/p4")
public String p4(@RequestBody ProductInfo productInfo){
    return api.p4(productInfo);
}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

测试远程调用:http://127.0.0.1:8080/order/p4
在这里插入图片描述

4. 最佳实践

通过观察,我们也能看出来,Feign的客户端与服务提供者的controller代码非常相似.
Feign客户端:

@FeignClient(value = "product-service")
public interface ProductApi {
    @RequestMapping("/product/p1")
    String p1(@RequestParam("id") Integer id);
}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

服务提供方Controller

@RestController
@RequestMapping("/product")
public class ProductController {
    @RequestMapping("/p1")
    public String p1(Integer id){
        return "接收到参数"+id;
    }
}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

有没有一种方法可以简化这种写法呢?

4.1 Feign继承方式

Feign支持继承的方式,我们可以把一些常见的操作封装到接口里.
我可以定义好一个接口,服务提供方实现这个接口,服务消费方编写Feign接口的时候,直接继承这个接口.
接口可以放在一个公共的jar包中,供服务提供方和服务消费方使用.

  1. 新建一个模块
    在这里插入图片描述
  2. 引入依赖
<dependencies>
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
    dependency>
    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-openfeignartifactId>
    dependency>
dependencies>
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
  1. 编写接口
    复制ProductInfo类和ProductApi到product-api模块中.把ProductApi改名为ProductInterface
    在这里插入图片描述
  2. 打jar包,并安装到本地Maven仓库
    在这里插入图片描述
    点击install.该模块就会被安装到本地的Maven仓库.
    在这里插入图片描述
    由于jar包中已经有了ProductInfo类,所以我们就可以把product-service和order-service的ProductInfo类注掉了.
  3. 服务提供方
    需要先在服务方中引入对应模块的依赖.
<dependency>
    <groupId>org.examplegroupId>
    <artifactId>product-apiartifactId>
    <version>1.0-SNAPSHOTversion>
    <scope>compilescope>
dependency>
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

服务方product-service直接实现接口ProductInterface.

@RestController
@RequestMapping("/product")
public class ProductController implements ProductInterface {
    @Autowired
    private ProductService productService;
    @RequestMapping("/select")
    public ProductInfo getProductInfo(Integer id){
        return productService.selectById(id);
    }
    @RequestMapping("/p1")
    public String p1(Integer id){
        return "接收到参数"+id;
    }
    @RequestMapping("/p2")
    public String p2(Integer id1,Integer id2){
        return "接收到参数1:" + id1 + ",接收到参数2:" + id2;
    }
    @RequestMapping("/p3")
    public String p3(ProductInfo productInfo){
        return "接收到对象:" + productInfo;
    }
    @RequestMapping("/p4")
    public String p4(@RequestBody ProductInfo productInfo){
        return "接收到对象:" + productInfo;
    }
}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"> class="hide-preCode-box">
  1. 服务消费方
    同样,首先先添加依赖.
    之后让FeignClient继承ProductInterface
@FeignClient(value = "product-service")
public interface ProductApi extends ProductInterface {

}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

注意在上述步骤中,把ProductInfo类引入包的路径全部改为之前打包的product-api模块下ProductInfo类的路径.

  1. 测试接口
    http://127.0.0.1:8080/order/select?id=1
    在这里插入图片描述

4.2 Feign抽取方式

官方推荐Feign的使用方式为继承的方式,但是企业开发中,更多是把Feign接口抽取为⼀个独立的模块(做法和继承相似,但理念不同).
操作方法:
将Feign的Client抽取为⼀个独立的模块,并把涉及到的实体类等都放在这个模块中,打成⼀个Jar.服务消费方只需要依赖该Jar包即可.这种方式在企业中比较常见,Jar包通常由服务提供方来实现.
前4步和前面继承的方式一样.只不过接口ProductApi在复制到新模块的时候不用修改名字
在这里插入图片描述

  1. 服务消费方使用product-api
    首先引入依赖,之后把该模块中原有的ProductApi接口注掉.
<dependency>
	<groupId>org.examplegroupId>
	<artifactId>product-apiartifactId>
	<version>1.0-SNAPSHOTversion>
dependency>
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

之后指定扫描类
在启动类中添加需要加载的Feign客户端.

@SpringBootApplication
@EnableFeignClients(clients = ProductApi.class)
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class,args);
    }
}
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
  1. 测试
    远程调用接口http://127.0.0.1:8080/order/select?id=1
    在这里插入图片描述
data-report-view="{"mod":"1585297308_001","spm":"1001.2101.3001.6548","dest":"https://lilesily12385.blog.csdn.net/article/details/145303771","extend1":"pc","ab":"new"}">>
注:本文转载自blog.csdn.net的PlutoZuo的文章"https://blog.csdn.net/PlutoZuo/article/details/132837865"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接

评论记录:

未查询到任何数据!