SpringCloud如何利用Feign訪問外部http請求
Feign訪問外部http請求
大家好,目前接手了一個項目,具體的邏輯并不復(fù)雜,主要是一個"中間商"角色, 比如客戶端通過我訪問高德地圖API,就不需要帶秘鑰,直接帶高德API所需的入?yún)⒑蛈rl后綴,就可以訪問。
目前遇到這樣一個問題,項目架構(gòu)師要求所有的項目自己寫的htttpClintUtils或者其他工具,需要替換到feign的形式來完成調(diào)用,但是,目前這個項目訪問外部的http接口很多,比如,提供的高德服務(wù)就有10多種,一共有大幾十類型,這樣的話,如果按照以前的方式,一個接口指定一個高德子服務(wù),那豈不是要累死 = =!
累死人的寫法:(僅參考)
@FeignClient(value = "test",url = "http://ip:port") public interface TestFeign { ? ? /** ? ? ?* @return 高德服務(wù)接口 ? ? ?* @description 訪問高德地理編碼服務(wù) ? ? ?*/ ? ? @PostMapping(value = "/Amap/geo") ? ? Object geo(@RequestBody GeoEntity entity); ? ? ? /** ? ? ?* @return 高德服務(wù)接口 ? ? ?* @description 訪問高德逆地理編碼服務(wù) ? ? ?*/ ? ? @PostMapping(value = "/Amap/regeo") ? ? Object regeo(@RequestBody RegeoEntity entity);?? ? ? ......... ? ? ........... }
然后如果我除了高德服務(wù)還有其他外部服務(wù),并且其他外部服務(wù)下的子接口,不一定就兩個,那這樣寫的話,要頭大死,并且這樣的寫法,在服務(wù)的內(nèi)部,不能做秘鑰和權(quán)限的動態(tài)配置,只能在url上做指定,比較笨拙,所以就需要一種可以靈活訪問外部httpClient的Feign接口,只需要我指定一個url,指定下提交的post數(shù)據(jù),就可以得到返回結(jié)果,豈不是美滋滋?
話不多說,先上pom.xml
?<dependency> ? ? ? ? ? ? <groupId>org.springframework.cloud</groupId> ? ? ? ? ? ? <artifactId>spring-cloud-starter-openfeign</artifactId> ? ? ? ? ? ? <version>2.0.1.RELEASE</version> ? ? ? ? </dependency> ? ? ? ? ? <dependency> ? ? ? ? ? ? <groupId>org.springframework.cloud</groupId> ? ? ? ? ? ? <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> ? ? ? ? ? ? <version>2.0.1.RELEASE</version> ? ? ? ? </dependency> ? ? ? ? ? <!-- 引入 httpclient --> ? ? ? ? <dependency> ? ? ? ? ? ? <groupId>org.apache.httpcomponents</groupId> ? ? ? ? ? ? <artifactId>httpclient</artifactId> ? ? ? ? </dependency> ? ? ? ? <dependency> ? ? ? ? ? ? <groupId>com.netflix.feign</groupId> ? ? ? ? ? ? <artifactId>feign-httpclient</artifactId> ? ? ? ? ? ? <version>8.18.0</version> ? ? ? ? </dependency>
前兩個是feign和服務(wù)降級用到的包,后兩個是用Apache Http替換原生的feign-http-client用來提供連接池等功能。
bootstap.yml 部分配置
feign: ? httpclient: ? ? enabled: true ? hystrix: ? ? enabled: true hystrix: ? command: ? ? default: ? ? ? execution: ? ? ? ? isolation: ? ? ? ? ? thread: ? ? ? ? ? ? timeoutInMilliseconds: 3000 ?#降級超時時間,我設(shè)置為3秒。 feign.retry默認超時時間是5s.
設(shè)置了個降級超時時間,還有啟動了feign訪問外部httpClient配置和服務(wù)降級配置。
在spingbootApplication啟動類上增加注解
@EnableFeignClients
@EnableHystrix
代碼部分:
public interface HttpRequestFeign {? ? ? @RequestLine("GET") ? ? String sendGetRequest(URI baseUri); ? ? ? @RequestLine("POST") ? ? String sendPostRequest(URI baseUri, Map map); }
調(diào)用部分,這里我在我的BaseController構(gòu)造注解,其他服務(wù)Controller繼承,提供調(diào)用能力:
?@Autowired ? ? public BaseController(Decoder decoder, Encoder encoder) { ? ? ? ? httpRequestFeign = Feign.builder().encoder(encoder).decoder(decoder) ? ? ? ? ? ? ? ? .target(Target.EmptyTarget.create(HttpRequestFeign.class));? ? ? } ?protected String httpPostSend( String url, Map map) { ? ? ? ? String response = ""; ? ? ? ? try { ? ? ? ? ? ? response = httpRequestFeign.sendPostRequest(new URI(url), map); ? ? ? ? ? ? logger.info("調(diào)用外部服務(wù)返回的數(shù)據(jù)為->{}", response); ? ? ? ? ? ? // 這里改成重試的超時異常 ? ? ? ? } catch (RetryableException a) { ? ? ? ? ? ? logger.error("調(diào)用外部服超時錯誤->{}", response); ? ? ? ? } catch (Exception e) { ? ? ? ? ? ? logger.error("調(diào)用外部服異常錯誤->{}", response); ? ? ? ? } ? ? ? ? return response; ? ? }
這里只列舉了Post的,Get方式,就不用了攜帶map參數(shù)了。
然后在你的Controller層增加降級@HystrixCommand注解,并指定降級方法:
?@HystrixCommand(fallbackMethod = "fallback") ?@PostMapping(value = "/1_0_0/{subServer}", produces = "application/json;charset=UTF-8") ?public Object send(@RequestBody Map<String, Object> map, @PathVariable String subServer) { ? ....................... ....................? ? ?private Object fallback(Map<String, String> map, String subserver, Throwable e) { ? ? ? ? logger.error("xxx服務(wù)發(fā)生問題,入?yún)?{},地址:{}", map, subserver); ? ? ? ? return Result.fail(ResultCode.INTERNAL_SERVER_ERROR.getCode(), ERROR_MSG + e.toString()); ? ? }
在send方法里可以自行進行拼接url,而Map就是傳遞給第三方服務(wù)的數(shù)據(jù)。
FeignClient外部http請求
springboot 4.0.0
pom.xml 引入openfeign 2.0.2
<dependencyManagement> ?? ??? ?<dependencies> ?? ??? ??? ?<dependency> ?? ??? ??? ??? ?<groupId>org.springframework.cloud</groupId> ?? ??? ??? ??? ?<artifactId>spring-cloud-openfeign</artifactId> ?? ??? ??? ??? ?<version>2.0.2.BUILD-SNAPSHOT</version> ?? ??? ??? ??? ?<type>pom</type> ?? ??? ??? ??? ?<scope>import</scope> ?? ??? ??? ?</dependency> ?? ??? ?</dependencies> ?? ?</dependencyManagement> ?? ?<dependencies> <!--外部http請求 FeignClient--> ?? ??? ?<dependency> ?? ??? ??? ?<groupId>org.springframework.cloud</groupId> ?? ??? ??? ?<artifactId>spring-cloud-starter-openfeign</artifactId> ?? ??? ?</dependency> </dependencies> <repositories> ?? ??? ?<!--外部http請求 FeignClient--> ?? ??? ?<repository> ?? ??? ??? ?<id>spring-snapshots</id> ?? ??? ??? ?<name>Spring Snapshots</name> ?? ??? ??? ?<url>https://repo.spring.io/libs-snapshot</url> ?? ??? ??? ?<snapshots> ?? ??? ??? ??? ?<enabled>true</enabled> ?? ??? ??? ?</snapshots> ?? ??? ?</repository> ?? ?</repositories>
啟動類 添加注解@EnableFeignClients
@SpringBootApplication @MapperScan("com.sichuang.repository.dao")//將項目中對應(yīng)的mapper類的路徑加進來就可以了 @ServletComponentScan @EnableFeignClients public class RepositoryApplication extends SpringBootServletInitializer{ ?? ?public static void main(String[] args) { ?? ??? ?SpringApplication.run(RepositoryApplication.class, args); ?? ?} ?? ?@Override ?? ?protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { ?? ??? ?// TODO Auto-generated method stub // ? ? ?return super.configure(builder); ?? ??? ?return builder.sources(RepositoryApplication.class); ?? ?} }
外部接口類。調(diào)用方式同service
@RequestParam 參數(shù)注解
produces = MediaType.APPLICATION_JSON_UTF8_VALUE 返回json參數(shù)
package com.sichuang.repository.api; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import java.util.Map; /** ?* 對接接口 ?* ?* @author xs ?* @date 2018/10/8 9:08 ?*/ @FeignClient(url = "${url}", name = "Ewaytec2001API") public interface Ewaytec2001API { ? ? /** ? ? ?*/ ? ? @GetMapping(value = "${url}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) ? ? String getEmployeeInfo(@RequestParam("id") int id, @RequestParam("sign") String sign); }
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java之Springcloud Gateway內(nèi)置路由案例講解
這篇文章主要介紹了Java之Springcloud Gateway內(nèi)置路由案例講解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-08-08Java多線程 Callable、Future 和FutureTask
這篇文章主要介紹Java多線程中的 Callable、Future 以及FutureTask,下面文章圍繞Java多線程的相關(guān)資料展開全文詳細內(nèi)容,需要的朋友可以參考一下2021-10-10Java ArrayList集合詳解(Java動態(tài)數(shù)組)
這篇文章主要介紹了Java ArrayList集合詳解(Java動態(tài)數(shù)組),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10Java實現(xiàn)Excel文件轉(zhuǎn)PDF(無水印無限制)
這篇文章主要為大家詳細介紹了如何利用Java語言實現(xiàn)Excel文件轉(zhuǎn)PDF的效果,并可以無水印、無限制。文中的示例代碼講解詳細,需要的可以參考一下2022-06-06