如何解决Feign调用的GET参数传递的问题
导读:本文共4732.5字符,通常情况下阅读需要16分钟。同时您也可以点击右侧朗读,来听本文内容。按键盘←(左) →(右) 方向键可以翻页。
摘要: 需求在消费方服务通过GET方式,访问服务提供方的接口,需要传递多参数,拆分成多个参数的方式访问,不太适合用在该场景,需要改造成合适的方式调用服务方的接口思考拆分成多个参数时,若GET请求的参数超过3个及以上时,便不适用该种方式请求服务,因为这样传递参数过于臃肿,可读性也比较差;若改造成POST请求的方式,虽然解决参数过多的问题,但是也带来了其他的开销,参数被放到... ...
目录
(为您整理了一些要点),点击可以直达。需求
在消费方服务通过GET方式,访问服务提供方的接口,需要传递多参数,拆分成多个参数的方式访问,不太适合用在该场景,需要改造成合适的方式调用服务方的接口
思考
拆分成多个参数时,若GET请求的参数超过3个及以上时,便不适用该种方式请求服务,因为这样传递参数过于臃肿,可读性也比较差;
若改造成POST请求的方式,虽然解决参数过多的问题,但是也带来了其他的开销,参数被放到了body里面,然后请求到服务方提供的接口,服务方的接口也改造成了POST方式,改变了原来的GET方式调用的初衷,不太友好;
可以在消费方调用Feign接口时,参数封装到body中,在组装Feign接口请求时,将body里面的参数取出来,转换为GET方式请求的参数,请求body的参数,然后发起请求,实现了GET方式访问服务方提供的接口;
以下是这三种调用方式的具体实现,可以根据适合自己的业务场景去使用,选择不同的方式请求调用:
GET方式请求①
请求DTO对象:
packagecom.springcloud.pojo;importjava.util.Date;publicclassRequets01DTO{privateDatestartTime;privateDateendTime;privateStringmessage;@OverridepublicStringtoString(){return"Requets01DTO{"+"startTime="+startTime+",endTime="+endTime+",message='"+message+'\''+'}';}publicDategetStartTime(){returnstartTime;}publicvoidsetStartTime(DatestartTime){this.startTime=startTime;}publicDategetEndTime(){returnendTime;}publicvoidsetEndTime(DateendTime){this.endTime=endTime;}publicStringgetMessage(){returnmessage;}publicvoidsetMessage(Stringmessage){this.message=message;}}
消费方的请求:
@AutowiredGetClient01getClient01;@GetMapping("/request/get/01")publicStringrequestGetOne(Requets01DTOrequets01DTO){returngetClient01.queryDataByGetRequest(requets01DTO.getStartTime(),requets01DTO.getEndTime(),requets01DTO.getMessage());}
Feign接口:
packagecom.springcloud.service;importorg.springframework.cloud.openfeign.FeignClient;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RequestParam;importjava.util.Date;@FeignClient(value="provider-8762",contextId="GetClient01")publicinterfaceGetClient01{/***GET方式请求①**@paramstartTime*@paramendTime*@parammessage*@return*/@GetMapping("/get/01")StringqueryDataByGetRequest(@RequestParam("startTime")DatestartTime,@RequestParam("endTime")DateendTime,@RequestParam("message")Stringmessage);}
服务提供方:
@RestControllerpublicclassRequestProviderController{@GetMapping("/get/01")publicStringqueryDataByGetRequest(@RequestParam("startTime")DatestartTime,@RequestParam("endTime")DateendTime,@RequestParam("message")Stringmessage){Requets01DTOrequets01DTO=newRequets01DTO();requets01DTO.setStartTime(startTime);requets01DTO.setEndTime(endTime);requets01DTO.setMessage(message);returnrequets01DTO.toString();}}
请求结果截图:
GET方式请求②
Feign调用的请求改为POST方式
消费方的请求:
@AutowiredGetClient02getClient02;@GetMapping("/request/get/02")publicStringrequestGetTwo(Requets01DTOrequets01DTO){returngetClient02.queryDataByGetRequest(requets01DTO);}
Feign接口:
packagecom.springcloud.service;importcom.springcloud.pojo.Requets01DTO;importorg.springframework.cloud.openfeign.FeignClient;importorg.springframework.web.bind.annotation.PostMapping;@FeignClient(value="provider-8762",contextId="GetClient02")publicinterfaceGetClient02{/***GET方式请求②(Feign调用的请求改为POST方式)**@paramrequets01DTO*@return*/@PostMapping("/post/02")StringqueryDataByGetRequest(Requets01DTOrequets01DTO);}
服务提供方:
@PostMapping("/post/02")publicStringqueryDataByGetRequest(@RequestBodyRequets01DTOrequets01DTO){returnrequets01DTO.toString();}
请求结果截图:
GET方式请求③
组装Feign接口请求时,将body里面的参数取出来,转换为GET方式请求的参数
添加Feign请求的配置类:
packagecom.springcloud.config;importcom.alibaba.fastjson.JSON;importfeign.Request;importfeign.RequestInterceptor;importfeign.RequestTemplate;importorg.springframework.context.annotation.Configuration;importorg.springframework.http.HttpMethod;importorg.springframework.web.context.request.RequestContextHolder;importorg.springframework.web.context.request.ServletRequestAttributes;importjavax.servlet.http.HttpServletRequest;importjava.lang.reflect.Field;importjava.util.*;@ConfigurationpublicclassFeignConfigurationimplementsRequestInterceptor{@Overridepublicvoidapply(RequestTemplaterequestTemplate){ServletRequestAttributesattributes=(ServletRequestAttributes)RequestContextHolder.getRequestAttributes();HttpServletRequestrequest=attributes.getRequest();//填充get中的body数据转化成query数据if(requestTemplate.method().equals(HttpMethod.GET.name())&&Objects.nonNull(requestTemplate.body())){Stringjson=requestTemplate.requestBody().asString();Map<String,Object>map=JSON.parseObject(json);Set<String>set=map.keySet();Iterator<String>it=set.iterator();while(it.hasNext()){Stringkey=it.next();Objectvalues=map.get(key);if(Objects.nonNull(values)){//将body的参数写入queriesrequestTemplate.query(key,values.toString());}}try{ClassrequestClass=requestTemplate.getClass();Fieldfield=requestClass.getDeclaredField("body");field.setAccessible(true);//修改body为空。field.set(requestTemplate,Request.Body.empty());}catch(Exceptionex){System.out.println(ex.fillInStackTrace());}}Enumeration<String>headerNames=request.getHeaderNames();if(headerNames!=null){while(headerNames.hasMoreElements()){Stringname=headerNames.nextElement();Stringvalues=request.getHeader(name);//跳过content-lengthif(name.equals("content-length")){continue;}requestTemplate.header(name,values);}}else{System.out.println(String.format("feigninterceptorerrorheader:%s",requestTemplate));}}}
添加fastJson的maven依赖:
<!--JSON解析器和生成器--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.74</version></dependency>
消费方的请求:
@AutowiredGetClient03getClient03;@GetMapping("/request/get/03")publicStringrequestGetThree(Requets01DTOrequets01DTO){returngetClient03.queryDataByGetRequest(requets01DTO);}
Feign接口:
packagecom.springcloud.service;importcom.springcloud.config.FeignConfiguration;importcom.springcloud.pojo.Requets01DTO;importorg.springframework.cloud.openfeign.FeignClient;importorg.springframework.web.bind.annotation.GetMapping;@FeignClient(value="provider-8762",contextId="GetClient03",configuration=FeignConfiguration.class)publicinterfaceGetClient03{/***GET方式请求③(组装Feign接口请求时,将body里面的参数取出来,转换为GET方式请求的参数)**@paramrequets01DTO*@return*/@GetMapping("/get/03")StringqueryDataByGetRequest(Requets01DTOrequets01DTO);}
服务提供方:
@GetMapping("/get/03")publicStringqueryDataByGetRequest03(Requets01DTOrequets01DTO){returnrequets01DTO.toString();}
请求结果截图:
Feign调用传递的GET参数日期,要指定jsonFormat注解,body转GET参数时,日期参数会变为字符串,需要指定日期格式
@JsonFormat(pattern="yyyy-MM-ddHH:mm:ss")@DateTimeFormat(pattern="yyyy-MM-ddHH:mm:ss")privateDatestartTime;@JsonFormat(pattern="yyyy-MM-ddHH:mm:ss")@DateTimeFormat(pattern="yyyy-MM-ddHH:mm:ss")privateDateendTime;
**结果截图:**
</div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
如何解决Feign调用的GET参数传递的问题的详细内容,希望对您有所帮助,信息来源于网络。