關(guān)于@RequestLine的使用及配置
@RequestLine的使用及配置
@RequestLine與其它請(qǐng)求不同,只需要簡(jiǎn)單寫(xiě)請(qǐng)求方式和路徑就能達(dá)到請(qǐng)求其它服務(wù)的目的。
@FeignClient(value = "feign-server",configuration = FeignConfig.class) ?//需要一個(gè)配置文件 public interface TestService { ? ? @RequestLine("POST /feign/test") ? ?//對(duì)應(yīng)請(qǐng)求方式和路徑 ? ? String feign(@RequestBody UserDO userDO); }
@EnableFeignClients @SpringBootConfiguration public class FeignConfig { ? ? @Bean ? ? public Contract contract(){ ? ? ? ? return new feign.Contract.Default(); ? ? } }
自定義配置feignClient并使用@RequestLine問(wèn)題
之前在項(xiàng)目里請(qǐng)求三方服務(wù)時(shí),使用的是restTemplate,其在組裝參數(shù)上略顯麻煩,其實(shí)我們可以使用openFeign自動(dòng)的組件去請(qǐng)求三方服務(wù),實(shí)現(xiàn)更加優(yōu)雅
步驟
依賴(lài)導(dǎo)入這些就不說(shuō)了,直接進(jìn)入正題
1. 定義請(qǐng)求接口
其寫(xiě)法和@FeignClient類(lèi)似,但要使用來(lái)自于openFeign的核心注解@RequestLine,而不是來(lái)自MVC的注解@PostMapping、@GetMapping。
public interface DhlApi { /** * 查詢(xún)軌跡 * @param url * @return */ @RequestLine("GET {url}") @Headers({ "Content-Type: application/json", }) DhlActiveQueryResponse queryTrack(@Param("url") String url); }
2. 定義配置文件,配置請(qǐng)求接口
@Configuration public class TestFeignConfig { // 獲取配置文件,自己用的是apollo @ApolloJsonValue("${test.api}") private TestISVInfo testIsvInfo; @Bean public TestISVInfo testIsvApi() throws Exception { return Feign.builder() .client(client()) .encoder(new FastJsonEncoder()) .decoder(new FastJsonDecoder()) // 連接超時(shí)30秒,讀取超時(shí)60秒 .options(new Request.Options(30 * 1000, 60 * 1000)) // 配置日志 .logger(new Slf4jLogger(TestFeignConfig.class)) // 發(fā)生IO異常重試5次,每次重試最小間隔100ms,最大間隔1s,隨著重試次數(shù)遞增 .retryer(new Retryer.Default()) .logLevel(Logger.Level.FULL) // 注冊(cè)feign .target(TestIsv.class, testIsvInfo.getDomainUrl()); } private Client client() throws Exception { // 信任策略,設(shè)置為無(wú)條件信任 TrustStrategy acceptingTrustStrategy = (cert, authType) -> true; // 設(shè)置ssl配置,由于我們采用無(wú)條件信任,所以也不需要加載證書(shū) SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build(); // 使用NoopHostnameVerifier關(guān)閉ssl的校驗(yàn) SSLConnectionSocketFactory sslScoketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE); Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create() .register("https", sslScoketFactory) .register("http", new PlainConnectionSocketFactory()) .build(); PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); CloseableHttpClient httpClient = HttpClients .custom() .setMaxConnTotal(20) .setMaxConnPerRoute(20) .setSSLSocketFactory(sslScoketFactory) .evictExpiredConnections() .evictIdleConnections(20, TimeUnit.SECONDS) .setConnectionManager(connectionManager).build(); return new ApacheHttpClient(httpClient); } }
結(jié)束!就這么簡(jiǎn)單。
為什么用的是@RequestLine
這和open-feign的Contract設(shè)計(jì)有關(guān)系,Contract是一個(gè)注解解析接口,它決定了接口可以使用什么注解轉(zhuǎn)換到http請(qǐng)求。open-feign在使用@FeignClient的情況下,使用的是SpringMvcContract,它使得被@FeignClient修飾的接口,可以使用@GetMapping,@PostMapping等Spring Mvc注解。
如果我們要使用@RequestLine,則需要替換open-Feign的MVC解析器,像這樣
// 在feign上寫(xiě)上配置 @FeignClient(name = "test-center", configuration = TestFeignConfig .class) // 配置類(lèi) @Configuration public class TestFeignConfig { // 配置feign的注釋解析器為feign默認(rèn)解析器而不是mvc解析器 @Bean public Contract feignContract() { return new feign.Contract.Default(); } }
如果我們不單獨(dú)配置,則會(huì)使用FeignClientsConfiguration中默認(rèn)配置的SpringMvcContract。
@Bean @ConditionalOnMissingBean public Contract feignContract(ConversionService feignConversionService) { return new SpringMvcContract(this.parameterProcessors, feignConversionService); }
那為什么我們通過(guò)@Bean形式注冊(cè)的feign客戶(hù)端就能直接使用@RequestLine呢。因?yàn)锧Bean形式注冊(cè)的feign客戶(hù)端不會(huì)使用這個(gè)配置,而是使用open-feign的默認(rèn)Contract
打開(kāi)這個(gè)類(lèi),我們可以看到它的描述,它的作用可以分為兩個(gè):
- 定義哪些注解在feign接口上是有校的
- 定義接口的動(dòng)作
它的processAnnotationOnMethod(MethodMetadata,Annotation, Method)方法,作用就是解析在feign接口上的注解,并轉(zhuǎn)化為發(fā)送http請(qǐng)求需要的數(shù)據(jù)。
方法代碼:
該類(lèi)的該方法,只會(huì)處理@Body、@RequestLine和@Header 3個(gè)注解,如果不是的話(huà),會(huì)直接跳過(guò)。 針對(duì)@RequestLIne:
獲取RequstLine的value,使用正則表達(dá)式判斷值是否是“GET xxxx”這類(lèi)的形式,不是就報(bào)錯(cuò)。解析到之后,獲得方法和uri設(shè)置進(jìn)RequestTemplate中針對(duì)@Body
將@Body中的值塞到RequestTemplate的body中針對(duì)@Headers
獲取@Header中的值,進(jìn)行解析,并放入RequestTemplate的Header中
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring Date jpa 獲取最新一條數(shù)據(jù)的實(shí)例代碼
這篇文章主要介紹了Spring Date jpa 獲取最新一條數(shù)據(jù)的實(shí)例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-10-10skywalking分布式服務(wù)調(diào)用鏈路追蹤APM應(yīng)用監(jiān)控
這篇文章主要為大家介紹了skywalking分布式服務(wù)調(diào)用鏈路追蹤APM應(yīng)用監(jiān)控的功能使用說(shuō)明,有需要的朋友可以借鑒參考下,希望能夠有所幫助2022-03-03Java通過(guò)PowerMockito和Mokito進(jìn)行單元測(cè)試的實(shí)現(xiàn)
PowerMockito和Mockito都是Java語(yǔ)言中的測(cè)試框架,用于進(jìn)行單元測(cè)試和集成測(cè)試,本文就來(lái)詳細(xì)的介紹一下通過(guò)PowerMockito和Mokito進(jìn)行單元測(cè)試,感興趣的可以了解一下2023-08-08Java編程實(shí)現(xiàn)基于用戶(hù)的協(xié)同過(guò)濾推薦算法代碼示例
這篇文章主要介紹了Java編程實(shí)現(xiàn)基于用戶(hù)的協(xié)同過(guò)濾推薦算法代碼示例,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11SpringMVC中的handlerMappings對(duì)象用法
這篇文章主要介紹了SpringMVC中的handlerMappings對(duì)象用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09SpringBoot?MongoCustomConversions自定義轉(zhuǎn)換方式
這篇文章主要介紹了SpringBoot?MongoCustomConversions自定義轉(zhuǎn)換方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08Java開(kāi)發(fā)學(xué)習(xí)之Bean的生命周期詳解
從創(chuàng)建到消亡的完整過(guò)程,例如人從出生到死亡的整個(gè)過(guò)程就是一個(gè)生命周期。本文將通過(guò)示例為大家詳細(xì)講講Bean的生命周期,感興趣的可以學(xué)習(xí)一下2022-06-06