刚开始接触feign时特别的抓狂,特别是那种有多个请求实体参数的接口,如果写多个请求体吧,报多个请求体异常,这个问题之所以抓狂,不是说它有多难以理解,难以使用,而是因为这是一个知识盲点,写博客的目的,一则记录并加深理解,二则能对需要的人有所帮助;
对@RequestBody和RequestParam理解如下
1.一个接口不能有多个请求体,倘若出现多个请求体的话会导致报多个请求体异常。
下面是对单个实体参数的接口调用案例:
feign调用分为中有三个组成结构:生产者,消费者,注册中心
生产者代码:
@PostMapping("comment")
// OrderCommentDTO是请求实体参数
public JsonResult comment( @RequestBody @Valid OrderCommentDTO formDTO,
HttpServletRequest request,
BindingResult e){
System.out.println("itemService端调用成功");
String resultId = request.getParameter("resultId");
System.out.println("测试参数传递:"+resultId);
if(e.hasErrors()){
return JsonResult.err();
} else {
return JsonResult.ok().msg("远程调用成功");
}
}
以上是生产者的代码,那么当遇到这样的代码时,你该如何调用呢,为解决这个问题我可是花费了半天的时间,如今想来也是不需要这么长时间的,只是当时太过于焦灼于代码本身的含义了,同时也在网上进行了大量的搜索,没有任何的效果,想着自己也写这么一篇博客,希望能对那些刚接触到feign的同学能有所帮助;如果,是你会如何调用,也许你会纠结于request里需要取出参数,我曾经就是纠结于这个问题,当然这点也是我的盲点,如果有哪位大神知道,还请多多指点,废话不多说,直接上代码:
消费者Controller层:
@PostMapping("/comment")
JsonResult comment(@RequestBoy @Valid OrderCommentDTO formDTO) {
System.out.println("feign端controller调用成功");
return itemServcie.comment(formDTO);
}
消费者Service层代码
@FeignClient(name="item-service",fallback = ItemFeignServiceFB.class)
public interface ItemFeignService {
@PostMapping("/comment")
public JsonResult comment(@RequestBody @Valid OrderCommentDTO formDTO);
}
就这样,远程调用完成了,
我们还会遇见这样的问题,就是被调用者(生产者)不在以上结构的位置呢,我可以负责任的回答你,这不影响的;
比如这样的位置:
@PostMapping("comment")
public JsonResult comment(HttpServletRequest request,
@RequestBody @Valid OrderCommentDTO formDTO,
BindingResult e){
System.out.println("itemService端调用成功");
String resultId = request.getParameter("resultId");
System.out.println("测试参数传递:"+resultId);
if(e.hasErrors()){
return JsonResult.err();
} else {
return JsonResult.ok().msg("远程调用成功");
}
}
@PostMapping("/test")
public JsonResult testParam(HttpServletRequest request,TestPo1 testPo1,TestPo2 testPo2,BindingResult e) {
return JsonResult.ok().msg("远程调用测试成功!!");
}
为了方便解说我每个请求体中都是一个参数(实际情况会超过一个参数),直接上代码吧:
@Data主要用于添加get和set方法
@Data
public class TestPo1 {
Integer id;
}
@Data
public class TestPo2 {
Integer ids;
}
消费者feign远程调用Service层
@FeignClient(name="item-service",fallback = ItemFeignServiceFB.class)
public interface ItemFeignService {
@PostMapping("/test")
JsonResult testFeignParam(
//注意引号内的参数名必须与被调用的接口的参数名相同
@RequestParam("id")Integer id,
@RequestParam("ids")Integer ids
);
}
消费者远程调用Controller层
@PostMapping("/test")
public JsonResult testFeignParam(TestPo1 testPo1,TestPo2 testPo2) {
return itemServcie.testFeignParam(testPo1.getId(),testPo2.getIds());
}
就这样子form-data格式的数据与实体类之间就完成了完美的调用;当然这种方法还可以使用于实体请求类参数但没有@RequestBody接口的调用。
3.当远程调用的参数是类型参数时,这种是最为简单的远程调用
@PostMapping("/test")
public JsonResult testParam(HttpServletRequest request,String testType1,Integer testType2,BindingResult e) {
return JsonResult.ok().msg("远程调用测试成功!!");
}
消费者feign远程调用Service层
@FeignClient(name="item-service",fallback = ItemFeignServiceFB.class)
public interface ItemFeignService {
@PostMapping("/test")
JsonResult testFeignParam(
//注意引号内的参数名必须与被调用的接口的参数名相同
@RequestParam("testType1")String testType1,
@RequestParam("testType2")Integer testType2
);
}
消费者远程调用Controller层
@PostMapping("/test")
public JsonResult testFeignParam(String testType1,Integer testType2) {
return itemServcie.testFeignParam(testType1,testType2);
}
4.当远程调用的接口实体类参数只有一个,但是没有@RequestBody注解实体类中又有较多的参数又该如何调用呢,这种倘若使用form-data的方式调用的话,请求实体参数过多呢,接口过于臃肿。
对于这种情况的调用方式在如下文章(这篇文章不是我所写,转载分享)以下是访问地址:
https://blog.csdn.net/w1054993544/article/details/104393871