0.引言
最近在讲解关于feign的组间调用,遇到了调用参数为实体类的GET请求报错或者参数获取为空问题,于是统一记录解决办法,方便大家后续参考
1. 原因
首先我们要知道,关于实体类参数,feign默认是支持post请求的。直接调用GET型的实体类参数接口会产生405报错或参数为空,如下所示
GET接口:
@GetMapping("getByBody2")
public String getByBody2(Product product){
return "product:" + JSON.toJSONString(product);
}
feign调用代码:
@GetMapping("getByBody2")
String getByBody2(Product product
报错内容:
这是因为feign本身就不支持这种形式的调用,他推荐的是转换为POST接口,但是有时,我们无法修改原接口,一定要求这种调用时,也不得不去解决,所以我们来看以下三种解决之法
2. 解决
方法1:参数转map
首先我们无法调用是因为不支持实体类参数,那么转换为键值对参数就可以实现调用了
参数转换:
@GetMapping("getBody2")
public String getBody2(){
Product product = new Product();
product.setId(1L);
product.setName("苹果");
product.setPrice(new BigDecimal("123.3"));
product.setQuantity(2);
// 实体类转json字符串 需要引入fastjson依赖
String jsonString = JSON.toJSONString(product);
// json字符串转map
Map params = JSON.parseObject(jsonString, Map.class);
return "order info " + productFeignNacos.getByBody2(params);
}
feign接口声明:
注意这种形式,需要添加@RequestParam注解,并命名与被调用接口参数名一致
@GetMapping("getByBody2")
String getByBody2(@RequestParam("product") Map product);
被调用接口:
@GetMapping("getByBody2")
public String getByBody2(Product product){
return "product:" + JSON.toJSONString(product);
}
方法2:利用@SpringQueryMap
注解自动转map
@SpringQueryMap
注解可以将实体类自动转换为map,那么我们就不需要手动转换成map了
feign接口声明
@GetMapping("getByBody2")
String getByBody3(@SpringQueryMap Product product);
方法3:利用feign-httpclient
工具包
feign-httpclient
工具包提供了支持GET实体参数的实现,我们只需要引入这个依赖即可
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
<version>10.10.1</version>
</dependency>
调用方代码:
@GetMapping("getBody4")
public String getBody4(){
Product product = new Product();
product.setId(1L);
product.setName("苹果");
product.setPrice(new BigDecimal("123.3"));
product.setQuantity(2);
return "order info " + productFeignNacos.getByBody4(product);
}
feign接口声明:
@GetMapping(value = "")
String getByBody4(Product product);
被调用接口:
@GetMapping(value = "getByBody3", consumes = MediaType.APPLICATION_JSON_VALUE)
public String getByBody3(@RequestBody Product product){
return "product:" + JSON.toJSONString(product);
}
调用结果展示
总结
如上,三种方式,任君挑选