SpringCloud OpenFeign 自定義響應(yīng)解碼器的問題記錄
一、JsonResult 在 OpenFeign 微服務(wù)調(diào)用的問題
我們?cè)谑褂?Spring Cloud 微服務(wù)的時(shí)候,通常將返回結(jié)果使用一個(gè)JsonResult 類進(jìn)行封裝,例如如下的格式:
public class JsonResult<T> { /* 響應(yīng)碼,200為成功 */ private Integer code; /* 失敗時(shí)的具體失敗信息 */ private String message; /* 成功時(shí)的數(shù)據(jù)對(duì)象 */ private T data; }
而調(diào)用方在使用Spring Cloud OpenFeign定義的客戶端調(diào)用遠(yuǎn)程服務(wù)時(shí),由于遠(yuǎn)程微服務(wù)接口的返回值也是 JsonResult 對(duì)象,這樣本地的接口也需要使用 JsonResult 進(jìn)行接收,這增加了額外的Result類重新拆開等工作。
有沒有辦法實(shí)現(xiàn)一些自定義的邏輯,比如將統(tǒng)一返回的Result類重新拆開僅返回對(duì)應(yīng)的業(yè)務(wù)對(duì)象,或者對(duì)特定的響應(yīng)碼進(jìn)行處理等等?
二、自定義 OpenFeign 響應(yīng)解碼器
為了實(shí)現(xiàn)上述功能,我們就需要改造默認(rèn)的Decoder。Spring Cloud OpenFeign允許我們?cè)诙x一個(gè)FeignClient 的時(shí)候,指定一個(gè)額外的配置類,比如:
@FeignClient( name = "xxx-base", path = "/api/base", configuration = CustomizedConfiguration.class /* 自定義配置類 */ ) public interface RemoteUserService { //.. }
我們可以在 CustomizedConfiguration 中定義一個(gè)自己的 Decoder 來(lái)覆蓋默認(rèn)的配置。
Spring Cloud 對(duì) Feign的封裝和默認(rèn)配置可以查看官方文檔。
自定義的 Decoder 需要實(shí)現(xiàn)feign.codec.Decoder接口,也可以參考默認(rèn)的Decoder的實(shí)現(xiàn)邏輯(org.springframework.cloud.openfeign.support.ResponseEntityDecoder),
下面的實(shí)現(xiàn)可以對(duì)統(tǒng)一返回值Result類的解包,并對(duì)異常返回進(jìn)行處理:
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("對(duì)象轉(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; } }
實(shí)現(xiàn)了Decoder之后,只需要將其配置到CustomizedConfiguration中即可。
三、為 FeignClient 注冊(cè)全局配置
注意如果CustomizedConfiguration添加了@Configuration的注解,則會(huì)成為Feign Client構(gòu)建的默認(rèn)配置,這樣就不需要在每個(gè)@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之后,如果一個(gè)遠(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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JAVA得到數(shù)組中最大值和最小值的簡(jiǎn)單實(shí)例
這篇文章主要介紹了JAVA得到數(shù)組中最大值和最小值的簡(jiǎn)單實(shí)例,需要的朋友可以參考下2014-08-08Spring實(shí)戰(zhàn)之使用Expression接口進(jìn)行表達(dá)式求值操作示例
這篇文章主要介紹了Spring實(shí)戰(zhàn)之使用Expression接口進(jìn)行表達(dá)式求值操作,結(jié)合實(shí)例形式分析了Spring操作Expression接口實(shí)現(xiàn)表達(dá)式運(yùn)算的操作技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下2019-12-12Java web網(wǎng)站訪問量的統(tǒng)計(jì)
這篇文章主要為大家詳細(xì)介紹了Java web網(wǎng)站訪問量的統(tǒng)計(jì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01JAVA利用接口實(shí)現(xiàn)多繼承問題的代碼實(shí)操演示
Java語(yǔ)言并不支持多繼承,這是由于多繼承會(huì)帶來(lái)許多復(fù)雜的問題,例如"菱形問題"等,下面這篇文章主要給大家介紹了關(guān)于JAVA利用接口實(shí)現(xiàn)多繼承問題的相關(guān)資料,需要的朋友可以參考下2024-03-03SpringBoot @ConfigurationProperties注解的簡(jiǎn)單使用
即便現(xiàn)在簡(jiǎn)化了配置,但是一個(gè)獨(dú)立的配置文件總是易于理解而且使人安心的。Spring在構(gòu)建完項(xiàng)目后,會(huì)默認(rèn)在resources文件夾下創(chuàng)建一個(gè)application.properties文件,application.yml也是一樣的效果。@ConfigurationProperties可以獲取配置文件中的數(shù)據(jù),將其注入類。2021-05-05MyBatis入門實(shí)例教程之創(chuàng)建一個(gè)簡(jiǎn)單的程序
這篇文章主要介紹了MyBatis入門創(chuàng)建一個(gè)簡(jiǎn)單的程序,在?MySQL?中創(chuàng)建數(shù)據(jù)庫(kù)?mybatisdemo,編碼為?utf8,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-02-02