[SpringCloud][14]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);  
}

目录结构为:

相关推荐
苍何2 分钟前
DeepSeek 的 Super-agent 设计,和我们的工程实践
后端
挖掘狂人2 分钟前
缓存和数据库的一致性,别停在 “延时双删”
java·后端·程序员
codigger9 分钟前
缓存和数据库的一致性,别停在 “延时双删”
java·后端·程序员·后端开发
10年前端老司机9 分钟前
Agent 商业化困局:热闹的发布会,冷清的付费客户
前端·后端·agent
小小张说故事14 分钟前
Python 的 async def 为什么能同时跑几千个任务?拆开协程对象、await 与事件循环那次让出
后端·python
小小龙学IT25 分钟前
Go 语言 pprof 性能剖析与调优深度解析:把“卡在哪“变成一张可执行的数据图
开发语言·后端·golang
Sailing27 分钟前
🚀🚀【封闭结束8】Agent RAG:从零搭建一个可用知识库
前端·后端·agent
Rain的Java大神之路37 分钟前
面试官让你把 LLM、RAG、Agent、MCP 串起来讲清楚,90% 的 Java 工程师当场露馅
java·后端·面试
余槐i1 小时前
Spring Boot 3.2 偶发500无日志:线程池复用导致请求上下文丢失
spring boot·redis·后端·mysql·性能优化
杨凯凡1 小时前
Spring Boot 的 @Transactional 为什么会失效?从代理、自调用到异常回滚的排查实战
java·spring boot·spring·事务·后端开发