SpringCloud OpenFeign 自定義響應(yīng)解碼器的問題記錄
一、JsonResult 在 OpenFeign 微服務(wù)調(diào)用的問題
我們在使用 Spring Cloud 微服務(wù)的時候,通常將返回結(jié)果使用一個JsonResult 類進行封裝,例如如下的格式:
public class JsonResult<T> { /* 響應(yīng)碼,200為成功 */ private Integer code; /* 失敗時的具體失敗信息 */ private String message; /* 成功時的數(shù)據(jù)對象 */ private T data; }
而調(diào)用方在使用Spring Cloud OpenFeign定義的客戶端調(diào)用遠(yuǎn)程服務(wù)時,由于遠(yuǎn)程微服務(wù)接口的返回值也是 JsonResult 對象,這樣本地的接口也需要使用 JsonResult 進行接收,這增加了額外的Result類重新拆開等工作。
有沒有辦法實現(xiàn)一些自定義的邏輯,比如將統(tǒng)一返回的Result類重新拆開僅返回對應(yīng)的業(yè)務(wù)對象,或者對特定的響應(yīng)碼進行處理等等?
二、自定義 OpenFeign 響應(yīng)解碼器
為了實現(xiàn)上述功能,我們就需要改造默認(rèn)的Decoder。Spring Cloud OpenFeign允許我們在定義一個FeignClient 的時候,指定一個額外的配置類,比如:
@FeignClient( name = "xxx-base", path = "/api/base", configuration = CustomizedConfiguration.class /* 自定義配置類 */ ) public interface RemoteUserService { //.. }
我們可以在 CustomizedConfiguration 中定義一個自己的 Decoder 來覆蓋默認(rèn)的配置。
Spring Cloud 對 Feign的封裝和默認(rèn)配置可以查看官方文檔。
自定義的 Decoder 需要實現(xiàn)feign.codec.Decoder接口,也可以參考默認(rèn)的Decoder的實現(xiàn)邏輯(org.springframework.cloud.openfeign.support.ResponseEntityDecoder),
下面的實現(xiàn)可以對統(tǒng)一返回值Result類的解包,并對異常返回進行處理:
public class CustomizedConfiguration{ @Bean public Decoder feignDecoder() { return new OpenFeignResultDecoder(); } }
public class OpenFeignResultDecoder implements Decoder { @Resource ObjectMapper objectMapper; @Override public Object decode(Response response, Type type) throws IOException, DecodeException, FeignException { String resultJson = this.getResponseBody(response); try { JavaType rawType = objectMapper.getTypeFactory().constructType(type); JavaType resultType = objectMapper.getTypeFactory().constructParametricType(JsonResult.class, rawType.getRawClass()); JsonResult<?> jsonResult = objectMapper.readValue(resultJson, resultType ); if (jsonResult.getCode() != HttpStatus.OK.value()){ throw new DecodeException( response.status(), jsonResult.getMessage(), response.request()); } return jsonResult.getData(); } catch (Exception ex){ throw new IllegalArgumentException("對象轉(zhuǎn)換失敗: " + ex.getMessage()); } } /* * 將 response body 解析為 string */ private static String getResponseBody(Response response) throws IOException { Response.Body resBody = response.body(); if (Objects.isNull(resBody)){ throw new DecodeException( response.status(), "返回體為空", response.request()); } String jsonStr; char[] buffer = new char[1024*4]; int len; try ( Reader reader = resBody.asReader(StandardCharsets.UTF_8); StringWriter strWriter = new StringWriter() ){ while ((len = reader.read(buffer)) != -1){ strWriter.write(buffer, 0, len); } jsonStr= strWriter.toString(); } return jsonStr; } }
實現(xiàn)了Decoder之后,只需要將其配置到CustomizedConfiguration中即可。
三、為 FeignClient 注冊全局配置
注意如果CustomizedConfiguration添加了@Configuration的注解,則會成為Feign Client構(gòu)建的默認(rèn)配置,這樣就不需要在每個@FeignClient注解中都去指定配置類了:
@Configuration public class OpenFeignConfig { @Bean public Decoder feignDecoder() { return new OpenFeignResultDecoder(); } }
@FeignClient( name = "xxx-base", path = "/api/base" ) public interface RemoteUserService { //.. }
四、使用 OpenFeign 遠(yuǎn)程服務(wù)示例
添加了自定義的Decoder之后,如果一個遠(yuǎn)程接口的定義是這樣的:
@FeignClient( name = "xxx-base", path = "/api/base" ) public interface RemoteUserService { @GetMapping(value = "/user/detail/{userId}") public User getUserDetailById(@PathVariable Integer userId) }
// ... @Resource RemouteUserService userService public void demoUserService(int userId){ User user = userService.getUserDetailById(userId); // .... }
到此這篇關(guān)于SpringCloud OpenFeign 自定義響應(yīng)解碼器的文章就介紹到這了,更多相關(guān)SpringCloud OpenFeign解碼器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring實戰(zhàn)之使用Expression接口進行表達式求值操作示例
這篇文章主要介紹了Spring實戰(zhàn)之使用Expression接口進行表達式求值操作,結(jié)合實例形式分析了Spring操作Expression接口實現(xiàn)表達式運算的操作技巧與相關(guān)注意事項,需要的朋友可以參考下2019-12-12SpringBoot @ConfigurationProperties注解的簡單使用
即便現(xiàn)在簡化了配置,但是一個獨立的配置文件總是易于理解而且使人安心的。Spring在構(gòu)建完項目后,會默認(rèn)在resources文件夾下創(chuàng)建一個application.properties文件,application.yml也是一樣的效果。@ConfigurationProperties可以獲取配置文件中的數(shù)據(jù),將其注入類。2021-05-05MyBatis入門實例教程之創(chuàng)建一個簡單的程序
這篇文章主要介紹了MyBatis入門創(chuàng)建一個簡單的程序,在?MySQL?中創(chuàng)建數(shù)據(jù)庫?mybatisdemo,編碼為?utf8,本文通過實例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-02-02