使用Feign遠(yuǎn)程調(diào)用時(shí),序列化對(duì)象失敗的解決
Feign遠(yuǎn)程調(diào)用序列化對(duì)象失敗
最近在搭建一個(gè)SpringCloud的微服務(wù)時(shí),遇到了一個(gè)問題,在使用Feign遠(yuǎn)程調(diào)用時(shí)報(bào)錯(cuò),返回對(duì)象沒有無參構(gòu)造方法,有其他的含參數(shù)的構(gòu)造方法。
本地自己搭建的微服務(wù)目錄大概如下,才剛開始,后續(xù)會(huì)逐漸補(bǔ)充優(yōu)化迭代,有興趣的可以fork下地址:
https://github.com/zhanghailang123/MyCloud
給與指導(dǎo)意見。
Eureka
:注冊(cè)中心服務(wù)端,采用Eureka注冊(cè)中心EurekaClientA
:其中的一個(gè)Eureka服務(wù)端,命名有點(diǎn)隨意,相當(dāng)于一個(gè)數(shù)據(jù)提供中心,暫時(shí)沒有使用ORM框架對(duì)接數(shù)據(jù)庫(kù),把相應(yīng)數(shù)據(jù)寫死了,目前只是在練習(xí)使用為了方便,后續(xù)考慮使用SpringJPA,因?yàn)镸b用的太多了FeignZ
:feign模塊遠(yuǎn)程調(diào)用加負(fù)載均衡,而且整合了Hystrix熔斷機(jī)制,當(dāng)然目前只做了最簡(jiǎn)單的Demo,練習(xí)下手感HystrixDashboard
:Hystrix儀表盤,可以關(guān)注下當(dāng)前的服務(wù)器狀況
RibbonZ
:主要用作于負(fù)載均衡,啟動(dòng)時(shí)可以啟動(dòng)EurekaClientA 多次指定不同的端口號(hào),來測(cè)試下負(fù)載均衡,一般都是用Feign直接遠(yuǎn)程調(diào)用,內(nèi)置了ribbon,這個(gè)demo中也是為了測(cè)試用的。TurBineZ
:用來監(jiān)控集群的熔斷情況。ZuulZ
:網(wǎng)關(guān)
接下來進(jìn)入正題。
場(chǎng)景: 在使用Feign遠(yuǎn)程調(diào)用寫死的數(shù)據(jù)服務(wù)EurekaClientA時(shí),報(bào)錯(cuò)如下
feign模塊如下:
此處為了復(fù)現(xiàn)問題,將熔斷邏輯暫時(shí)注釋掉
此處報(bào)錯(cuò)信息:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `org.example.pojo.Student` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
報(bào)錯(cuò)的對(duì)象 :org.example.pojo.Student 如下,一個(gè)很簡(jiǎn)單的bean對(duì)象:
那為什么會(huì)報(bào)這個(gè)問題呢 :不存在無參構(gòu)造函數(shù),序列化失敗
帶著疑問走進(jìn)報(bào)錯(cuò)的地方:
可以看到是這個(gè)地方 canInstantiate()方法校驗(yàn)沒通過。在此處打個(gè)斷點(diǎn)一探究竟
這個(gè)校驗(yàn)里面內(nèi)容是:
總之都是校驗(yàn)無參構(gòu)造函數(shù)。如果給調(diào)用的student對(duì)象加上無參構(gòu)造函數(shù)就可以成功調(diào)用。
構(gòu)造函數(shù)就可以成功調(diào)用。**
問題倒不是什么大問題,在搭建服務(wù)過程中,只有親力親為,切實(shí)參與到了,才能感受到各種奇奇怪怪的小問題,也只有這樣自己親自動(dòng)手,才是收獲最大的。
Feign做遠(yuǎn)程調(diào)用的注意點(diǎn)
在使用feign的過程中遇到了一些問題,所以在這里做以下總結(jié)
1.定義的做遠(yuǎn)程調(diào)用的api接口
中的方法參數(shù)列表中的參數(shù)都必須都要打上@RequestParam(“value”) 注解**,否則調(diào)用會(huì)報(bào)405異常,這一點(diǎn)是和controller中不一樣的,controller中的方法只要參數(shù)名和前臺(tái)傳入的參數(shù)鍵名對(duì)應(yīng)上就能自動(dòng)綁定上參數(shù)
復(fù)雜類型用必須打上@RequestBody注解
2.service微服務(wù)中的Controller的參數(shù)綁定
如果參數(shù)列表中有復(fù)雜類型,請(qǐng)使用Post請(qǐng)求,使用Get請(qǐng)求會(huì)報(bào)Bad Request錯(cuò)誤,且需要打上@RequestBody注解,而普通基本類型可以不用打上@RequestParam注解可自動(dòng)綁定參數(shù)
如有其它問題,也歡迎補(bǔ)充,放一下代碼:
api:
@FeignClient("MS-ADMIN-SERVICE") public interface FixFeignService { @GetMapping("/fix") public List<FixInfo> findAll(); @PostMapping("/fix/add") public int insert(@RequestBody FixInfo fixInfo); @PostMapping("/fix/limitByParam") public LayUIPageBean limitByParam(@RequestBody FixInfo fixInfo, @RequestParam("page") Integer page, @RequestParam("limit") Integer limit); @PostMapping("/fix/delByIds") public boolean delByIds(@RequestParam("ids[]") Long[] ids); @GetMapping("/fix/findById") public FixInfo findById(@RequestParam("id") Long id); @PostMapping("/fix/update") boolean update(@RequestBody FixInfo fixInfo); }
service微服務(wù)
@RestController @RequestMapping("/fix") @Slf4j public class FixInfoController { @Autowired private FixInfoService fixInfoService; @GetMapping("") public List<FixInfo> findAll(){ List<FixInfo> all = fixInfoService.findAll(); return all; } @PostMapping("/add") public int insert(@RequestBody FixInfo fixInfo){ return fixInfoService.insert(fixInfo); } @PostMapping("/limitByParam") public LayUIPageBean limitByParam(@RequestBody FixInfo fixInfo,Integer page,Integer limit){ LayUIPageBean layUIPageBean = new LayUIPageBean(); PageHelper.startPage(page,limit); List<FixInfo> all = fixInfoService.findByParam(fixInfo); PageInfo<FixInfo> pageInfo = new PageInfo<>(all); return layUIPageBean.setCount((int)pageInfo.getTotal()).setData(pageInfo.getList()); } @PostMapping("/delByIds") public boolean delByIds(@RequestParam("ids[]") Long[] ids){ //log.info("id"+ids[0]); boolean flag= fixInfoService.delByIds(ids); return flag; } @GetMapping("/findById") public FixInfo findById(Long id){ return fixInfoService.findById(id); } @PostMapping("/update") public boolean update(@RequestBody FixInfo fixInfo){ return fixInfoService.update(fixInfo); } }
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- Feign遠(yuǎn)程調(diào)用傳遞對(duì)象參數(shù)并返回自定義分頁(yè)數(shù)據(jù)的過程解析
- feign遠(yuǎn)程調(diào)用無法傳遞對(duì)象屬性405的問題
- Feign遠(yuǎn)程調(diào)用參數(shù)里面內(nèi)容丟失的解決方案
- Feign遠(yuǎn)程調(diào)用Multipartfile參數(shù)處理
- spring cloud feign實(shí)現(xiàn)遠(yuǎn)程調(diào)用服務(wù)傳輸文件的方法
- 解決在微服務(wù)環(huán)境下遠(yuǎn)程調(diào)用feign和異步線程存在請(qǐng)求數(shù)據(jù)丟失問題
相關(guān)文章
哈希表在算法題目中的實(shí)際應(yīng)用詳解(Java)
散列表(Hash?table,也叫哈希表)是根據(jù)關(guān)鍵碼值(Key?value)而直接進(jìn)行訪問的數(shù)據(jù)結(jié)構(gòu),下面這篇文章主要給大家介紹了關(guān)于哈希表在算法題目中的實(shí)際應(yīng)用,文中介紹的方法是Java,需要的朋友可以參考下2024-03-03SpringBoot動(dòng)態(tài)數(shù)據(jù)源連接測(cè)試的操作詳解
這篇文章主要介紹了SpringBoot動(dòng)態(tài)數(shù)據(jù)源連接測(cè)試的操作步驟,文中通過代碼示例和圖文結(jié)合的方式給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-03-03Spring Security學(xué)習(xí)之rememberMe自動(dòng)登錄的實(shí)現(xiàn)
這篇文章主要給大家介紹了關(guān)于Spring Security學(xué)習(xí)之rememberMe自動(dòng)登錄的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06