解決Feign調(diào)用的GET參數(shù)傳遞的問題
需求
? 在消費方服務通過GET方式,訪問服務提供方的接口,需要傳遞多參數(shù),拆分成多個參數(shù)的方式訪問,不太適合用在該場景,需要改造成合適的方式調(diào)用服務方的接口
思考
拆分成多個參數(shù)時,若GET請求的參數(shù)超過3個及以上時,便不適用該種方式請求服務,因為這樣傳遞參數(shù)過于臃腫,可讀性也比較差;
若改造成POST請求的方式,雖然解決參數(shù)過多的問題,但是也帶來了其他的開銷,參數(shù)被放到了body里面,然后請求到服務方提供的接口,服務方的接口也改造成了POST方式,改變了原來的GET方式調(diào)用的初衷,不太友好;
? 可以在消費方調(diào)用Feign接口時,參數(shù)封裝到body中,在組裝Feign接口請求時,將body里面的參數(shù)取出來,轉(zhuǎn)換為GET方式請求的參數(shù),請求body的參數(shù),然后發(fā)起請求,實現(xiàn)了GET方式訪問服務方提供的接口;
以下是這三種調(diào)用方式的具體實現(xiàn),可以根據(jù)適合自己的業(yè)務場景去使用,選擇不同的方式請求調(diào)用:
GET方式請求①
請求DTO對象:
package com.springcloud.pojo;? import java.util.Date;?? public class Requets01DTO {? ? ? private Date startTime;? ? ? private Date endTime;? ? ? private String message; ? ? ? @Override ? ? public String toString() { ? ? ? ? return "Requets01DTO{" + ? ? ? ? ? ? ? ? "startTime=" + startTime + ? ? ? ? ? ? ? ? ", endTime=" + endTime + ? ? ? ? ? ? ? ? ", message='" + message + '\'' + ? ? ? ? ? ? ? ? '}'; ? ? } ? ? ? public Date getStartTime() { ? ? ? ? return startTime; ? ? } ? ? ? public void setStartTime(Date startTime) { ? ? ? ? this.startTime = startTime; ? ? } ? ? ? public Date getEndTime() { ? ? ? ? return endTime; ? ? } ? ? ? public void setEndTime(Date endTime) { ? ? ? ? this.endTime = endTime; ? ? } ? ? ? public String getMessage() { ? ? ? ? return message; ? ? } ? ? ? public void setMessage(String message) { ? ? ? ? this.message = message; ? ? } }
消費方的請求:
? ? @Autowired ? ? GetClient01 getClient01; ? ? ? @GetMapping("/request/get/01") ? ? public String requestGetOne(Requets01DTO requets01DTO) { ? ? ? ? return getClient01.queryDataByGetRequest(requets01DTO.getStartTime(), requets01DTO.getEndTime(), requets01DTO.getMessage()); ? ? }
Feign接口:
package com.springcloud.service;? import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam;? import java.util.Date; ? @FeignClient(value = "provider-8762", contextId = "GetClient01") public interface GetClient01 { ? ? ? /** ? ? ?* GET方式請求① ? ? ?* ? ? ?* @param startTime ? ? ?* @param endTime ? ? ?* @param message ? ? ?* @return ? ? ?*/ ? ? @GetMapping("/get/01") ? ? String queryDataByGetRequest(@RequestParam("startTime") Date startTime, @RequestParam("endTime") Date endTime, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?@RequestParam("message") String message); }
服務提供方:
@RestController public class RequestProviderController { ? ? ? @GetMapping("/get/01") ? ? public String queryDataByGetRequest(@RequestParam("startTime") Date startTime, @RequestParam("endTime") Date endTime, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @RequestParam("message") String message) { ? ? ? ? Requets01DTO requets01DTO = new Requets01DTO(); ? ? ? ? requets01DTO.setStartTime(startTime); ? ? ? ? requets01DTO.setEndTime(endTime); ? ? ? ? requets01DTO.setMessage(message); ? ? ? ? return requets01DTO.toString(); ? ? } }
請求結(jié)果截圖:
GET方式請求②
Feign調(diào)用的請求改為POST方式
消費方的請求:
? ? @Autowired ? ? GetClient02 getClient02; ? ? ? @GetMapping("/request/get/02") ? ? public String requestGetTwo(Requets01DTO requets01DTO) { ? ? ? ? return getClient02.queryDataByGetRequest(requets01DTO); ? ? }
Feign接口:
package com.springcloud.service;? import com.springcloud.pojo.Requets01DTO; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.PostMapping; ? @FeignClient(value = "provider-8762", contextId = "GetClient02") public interface GetClient02 {? ? ? ? /** ? ? ?* GET方式請求②(Feign調(diào)用的請求改為POST方式) ? ? ?* ? ? ?* @param requets01DTO ? ? ?* @return ? ? ?*/ ? ? @PostMapping("/post/02") ? ? String queryDataByGetRequest(Requets01DTO requets01DTO); }
服務提供方:
? ? @PostMapping("/post/02") ? ? public String queryDataByGetRequest(@RequestBody Requets01DTO requets01DTO) { ? ? ? ? return requets01DTO.toString(); ? ? }
請求結(jié)果截圖:
GET方式請求③
組裝Feign接口請求時,將body里面的參數(shù)取出來,轉(zhuǎn)換為GET方式請求的參數(shù)
添加Feign請求的配置類:
package com.springcloud.config;? import com.alibaba.fastjson.JSON; import feign.Request; import feign.RequestInterceptor; import feign.RequestTemplate; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; ? import javax.servlet.http.HttpServletRequest; import java.lang.reflect.Field; import java.util.*; ? @Configuration public class FeignConfiguration implements RequestInterceptor { ? ? ? @Override ? ? public void apply(RequestTemplate requestTemplate) { ? ? ? ? ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); ? ? ? ? HttpServletRequest request = attributes.getRequest(); ? ? ? ? ? //填充get中的body數(shù)據(jù)轉(zhuǎn)化成query數(shù)據(jù) ? ? ? ? if (requestTemplate.method().equals(HttpMethod.GET.name()) && Objects.nonNull(requestTemplate.body())) { ? ? ? ? ? ? String json = requestTemplate.requestBody().asString(); ? ? ? ? ? ? Map<String, Object> map = JSON.parseObject(json); ? ? ? ? ? ? Set<String> set = map.keySet(); ? ? ? ? ? ? Iterator<String> it = set.iterator(); ? ? ? ? ? ? while (it.hasNext()) { ? ? ? ? ? ? ? ? String key = it.next(); ? ? ? ? ? ? ? ? Object values = map.get(key); ? ? ? ? ? ? ? ? if (Objects.nonNull(values)) { ? ? ? ? ? ? ? ? ? ? // 將body的參數(shù)寫入queries ? ? ? ? ? ? ? ? ? ? requestTemplate.query(key, values.toString()); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? ? ? ? try{ ? ? ? ? ? ? ? ? Class requestClass = requestTemplate.getClass(); ? ? ? ? ? ? ? ? Field field = requestClass.getDeclaredField("body"); ? ? ? ? ? ? ? ? field.setAccessible(true); ? ? ? ? ? ? ? ? //修改body為空。 ? ? ? ? ? ? ? ? field.set(requestTemplate, Request.Body.empty()); ? ? ? ? ? ? } catch (Exception ex) { ? ? ? ? ? ? ? ? System.out.println(ex.fillInStackTrace()); ? ? ? ? ? ? }? ? ? ? ? } ? ? ? ? ? Enumeration<String> headerNames = request.getHeaderNames(); ? ? ? ? if (headerNames != null) { ? ? ? ? ? ? while (headerNames.hasMoreElements()) { ? ? ? ? ? ? ? ? String name = headerNames.nextElement(); ? ? ? ? ? ? ? ? String values = request.getHeader(name); ? ? ? ? ? ? ? ? // 跳過 content-length ? ? ? ? ? ? ? ? if (name.equals("content-length")){ ? ? ? ? ? ? ? ? ? ? continue; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? requestTemplate.header(name, values); ? ? ? ? ? ? } ? ? ? ? } else { ? ? ? ? ? ? System.out.println(String.format("feign interceptor error header:%s", requestTemplate)); ? ? ? ? } ? ? } }
添加fastJson的maven依賴:
<!-- JSON 解析器和生成器 --> ? ? ? ? <dependency> ? ? ? ? ? ? <groupId>com.alibaba</groupId> ? ? ? ? ? ? <artifactId>fastjson</artifactId> ? ? ? ? ? ? <version>1.2.74</version> ? ? ? ? </dependency>
消費方的請求:
? ? @Autowired ? ? GetClient03 getClient03; ? ? ? @GetMapping("/request/get/03") ? ? public String requestGetThree(Requets01DTO requets01DTO) { ? ? ? ? return getClient03.queryDataByGetRequest(requets01DTO); ? ? }
Feign接口:
package com.springcloud.service;? import com.springcloud.config.FeignConfiguration; import com.springcloud.pojo.Requets01DTO; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; ? @FeignClient(value = "provider-8762", contextId = "GetClient03", configuration = FeignConfiguration.class) public interface GetClient03 { ? ? ? /** ? ? ?* GET方式請求③(組裝Feign接口請求時,將body里面的參數(shù)取出來,轉(zhuǎn)換為GET方式請求的參數(shù)) ? ? ?* ? ? ?* @param requets01DTO ? ? ?* @return ? ? ?*/ ? ? @GetMapping("/get/03") ? ? String queryDataByGetRequest(Requets01DTO requets01DTO); }
服務提供方:
? ? @GetMapping("/get/03") ? ? public String queryDataByGetRequest03(Requets01DTO requets01DTO) { ? ? ? ? return requets01DTO.toString(); ? ? }
請求結(jié)果截圖:
Feign調(diào)用傳遞的GET參數(shù)日期,要指定jsonFormat注解,body轉(zhuǎn)GET參數(shù)時,日期參數(shù)會變?yōu)樽址?,需要指定日期格?/p>
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date startTime; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date endTime;
**結(jié)果截圖:**
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java JDK動態(tài)代理(AOP)用法及實現(xiàn)原理詳解
在本篇文章了小編給大家整理的是一篇關(guān)于Java JDK動態(tài)代理(AOP)用法及實現(xiàn)原理詳解內(nèi)容,有需要的朋友們可以參考學習下。2020-10-10MySQL查詢字段實現(xiàn)字符串分割split功能的示例代碼
本文主要介紹了MySQL查詢字段實現(xiàn)字符串分割split功能的示例代碼,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01Java實現(xiàn)讀取鍵盤輸入保存到txt文件,再統(tǒng)計并輸出每個單詞出現(xiàn)次數(shù)的方法
這篇文章主要介紹了Java實現(xiàn)讀取鍵盤輸入保存到txt文件,再統(tǒng)計并輸出每個單詞出現(xiàn)次數(shù)的方法,涉及java文件I/O操作及字符串遍歷、運算實現(xiàn)統(tǒng)計功能相關(guān)技巧,需要的朋友可以參考下2017-07-07Java求10到100000之間的水仙花數(shù)算法示例
這篇文章主要介紹了Java求10到100000之間的水仙花數(shù)算法,結(jié)合實例形式分析了水仙花數(shù)的概念及相應的java算法實現(xiàn)技巧,需要的朋友可以參考下2017-10-10解決 IDEA 創(chuàng)建 Gradle 項目沒有src目錄問題
這篇文章主要介紹了解決 IDEA 創(chuàng)建 Gradle 項目沒有src目錄問題,本文圖文并茂給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2018-06-06解決mapper.xml中resultType映射類型的問題
這篇文章主要介紹了解決mapper.xml中resultType映射類型的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-06-06Spring Cloud實現(xiàn)提供API給客戶端的方法詳解
這篇文章主要給大家介紹了關(guān)于Spring Cloud實現(xiàn)提供API給客戶端的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。2018-01-01