SpringCloud使用feign远程调用之@RequestBody与@RequestParam注解实例(远程调用变得容易)

SpringCloud使用feign远程调用之@RequestBody与@RequestParam注解实例

刚开始接触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("远程调用成功");
    }
}
  1. 当然你也会遇见这样的情况,就是一个接口居然有两个请求实体参数,虽然是有点奇葩,但是问题还是得解决:
    直接上生产者的代码(为了增加参数的的复杂度故意多加了几个参数,但是调用过程换汤不换药,去掉HttpServletRequest request,BindingResult e两个请求参数不影响调用的), 这里的解决方案是使用form-data(请求表单)请求格式:
@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

你可能感兴趣的:(SpringCloud使用feign远程调用之@RequestBody与@RequestParam注解实例(远程调用变得容易))