溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

使用Feign遠(yuǎn)程調(diào)用時(shí)序列化對(duì)象失敗怎么解決

發(fā)布時(shí)間:2021-07-08 15:42:00 來源:億速云 閱讀:891 作者:chen 欄目:開發(fā)技術(shù)

本篇內(nèi)容介紹了“使用Feign遠(yuǎn)程調(diào)用時(shí)序列化對(duì)象失敗怎么解決”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

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ù)器狀況

使用Feign遠(yuǎn)程調(diào)用時(shí)序列化對(duì)象失敗怎么解決

  • 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)

使用Feign遠(yuǎn)程調(diào)用時(shí)序列化對(duì)象失敗怎么解決

接下來進(jìn)入正題。

場(chǎng)景: 在使用Feign遠(yuǎn)程調(diào)用寫死的數(shù)據(jù)服務(wù)EurekaClientA時(shí),報(bào)錯(cuò)如下

feign模塊如下:

使用Feign遠(yuǎn)程調(diào)用時(shí)序列化對(duì)象失敗怎么解決

此處為了復(fù)現(xiàn)問題,將熔斷邏輯暫時(shí)注釋掉

使用Feign遠(yuǎn)程調(diào)用時(shí)序列化對(duì)象失敗怎么解決

此處報(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ì)象:

使用Feign遠(yuǎn)程調(diào)用時(shí)序列化對(duì)象失敗怎么解決

那為什么會(huì)報(bào)這個(gè)問題呢 :不存在無參構(gòu)造函數(shù),序列化失敗

帶著疑問走進(jìn)報(bào)錯(cuò)的地方:

使用Feign遠(yuǎn)程調(diào)用時(shí)序列化對(duì)象失敗怎么解決

可以看到是這個(gè)地方 canInstantiate()方法校驗(yàn)沒通過。在此處打個(gè)斷點(diǎn)一探究竟

使用Feign遠(yuǎn)程調(diào)用時(shí)序列化對(duì)象失敗怎么解決

這個(gè)校驗(yàn)里面內(nèi)容是:

使用Feign遠(yuǎn)程調(diào)用時(shí)序列化對(duì)象失敗怎么解決

總之都是校驗(yàn)無參構(gòu)造函數(shù)。如果給調(diào)用的student對(duì)象加上無參構(gòu)造函數(shù)就可以成功調(diào)用。

使用Feign遠(yuǎn)程調(diào)用時(shí)序列化對(duì)象失敗怎么解決

構(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);
    }
}

“使用Feign遠(yuǎn)程調(diào)用時(shí)序列化對(duì)象失敗怎么解決”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI