Spring Cloud下使用Feign Form實(shí)現(xiàn)微服務(wù)之間的文件上傳

背景

? Spring Cloud現(xiàn)在已經(jīng)被越來越多的公司采用了谆沃,微服務(wù)架構(gòu)比傳統(tǒng)意義上的單服務(wù)架構(gòu)從復(fù)雜度上多了很多匀借,出現(xiàn)了很多復(fù)雜的場景乘碑。比如熊镣,我們的產(chǎn)品是個app扇雕,支持第三方登錄功能拓售,在手機(jī)端調(diào)用第三方授權(quán)接口之后,返回了用戶的相關(guān)信息镶奉,比如open_id础淤,性別崭放,頭像等。這些信息我們需要保存在我們服務(wù)器上鸽凶,當(dāng)時針對頭像是應(yīng)該保存圖片的url還是圖片本身發(fā)生了歧義币砂,在一番討論之后,得出的結(jié)果是玻侥,我們需要通過url將圖片下載到我們本地决摧,然后調(diào)用我們自己的文件微服務(wù)中上傳功能保存起來。

工具

IDE :IntelliJ IDEA

JDK : jdk 8

構(gòu)建工具:Gradle 4.10.2

Spring Cloud 版本:Finchley.SR2 (截止2018-11-25最新的GA版本凑兰,基于boot 2.0.6)

Spring Boot 版本:2.0.6.RELEASE (截止2018-11-25最新為2.1.0.RELEASE)

此處采用Gradle而沒有使用Maven作為依賴構(gòu)建和管理的工具掌桩,主要原因是我們公司目前使用的是Gradle,而且從編譯速度姑食,代碼可讀性和清晰度上都遠(yuǎn)遠(yuǎn)優(yōu)于Maven波岛。

項目結(jié)構(gòu)

? 本項目分為三個角色,分別如下:

eureka-server : 注冊中心

provider-server: 服務(wù)提供者音半,此處模擬一個文件服務(wù)器则拷,提供文件上傳功能

consumer-server: 服務(wù)消費(fèi)者,此處模擬一個業(yè)務(wù)服務(wù)祟剔,需要調(diào)用文件上傳服務(wù)

大致的依賴圖如下:

配置并運(yùn)行

? 我們首先通過運(yùn)行感受一下通過Feign上傳文件的流程隔躲,在整個項目可以完整運(yùn)行后,我們再參考文章和代碼一起分析其中設(shè)置物延,并將其應(yīng)用到自己的應(yīng)用中

首先clone項目到本地

gitclonehttps://github.com/Shiyajian/examples.git

安裝并配置Gradle

將項目導(dǎo)入到IDEA中

確認(rèn)IDEA支持Lombok插件宣旱,默認(rèn)IDEA都支持的,此步驟可忽略

更改IDEA設(shè)置叛薯,Project Settings(Mac中為Preferences)-> Compiler -> Annoatation Processors -> [√] Enable annotation processing

刷新Gradle浑吟,下載依賴并編譯

啟動注冊中心

找到 examples/spring-cloud/eureka-server中的EurekaApplication,運(yùn)行main方法

打開瀏覽器耗溜,運(yùn)行:http://localhost:8761/组力,能打開證明成功

啟動Provider項目

找到 examples/spring-cloud/chapter1/provider/provider-service中的ProviderApplication,運(yùn)行main方法

刷新注冊中心頁面抖拴,找到服務(wù)證明成功

運(yùn)行Consumer項目中的測試

打開examples/spring-cloud/chapter1/consumer/consumer-server/src/test目錄

修改com.shiyajian.examples.consumer.service.impl.ConsumerServiceImplTest類中文件的路徑為本機(jī)電腦上存在的文件

運(yùn)行測試方法

方法綠燈結(jié)束燎字,在控制臺能找到輸出為成功

Provider 服務(wù)配置說明

Provider服務(wù)為上傳服務(wù)的提供者,這里模擬的是一個文件服務(wù)器阿宅,通過上面圖候衍,我們可以看到項目分為2部分,下面就進(jìn)行詳細(xì)解讀:

provider-api

這個項目最終打成一個可以被引用的jar包洒放,consumer-server通過引用這個jar包可以通過注入方式引用其中的方法蛉鹿,provider-server也需要引用這個jar包,然后實(shí)現(xiàn)其中的邏輯往湿,供consumer-server遠(yuǎn)程調(diào)用妖异。配置api的方法如下:

添加org.springframework.cloud:spring-cloud-starter-openfeign依賴惋戏,只需要這一個依賴就夠了,里面保存Fegin-Form等依賴他膳。

編寫配置類FeignMultipartSupportConfig.java

publicclassFeignMultipartSupportConfig{@Bean@Primary@Scope("prototype") public Encoder multipartFormEncoder(ObjectFactory messageConverters) {returnnewFeignSpringFormEncoder(new SpringEncoder(messageConverters)); }}

編寫自定義的Encoder响逢,因為這個有個設(shè)計得BUG,本身可以解析文件數(shù)組矩乐,但是代碼缺少對應(yīng)的判斷龄句,此處參考文章:https://blog.csdn.net/tony_lu229/article/details/73823757,代碼不貼了散罕,詳細(xì)見工程

定義自己的接口,這里我定義的是ProviderClient傀蓉,代碼簡單如下:

@FeignClient(value ="provider-server", configuration = FeignMultipartSupportConfig.class)public interface ProviderClient {@PostMapping(value ="client/upload/{id}", consumes = MULTIPART_FORM_DATA_VALUE) String uploadFile(@RequestPart("file") MultipartFile file,@PathVariable("id") String id,@RequestParam("name") String name);@PostMapping(value ="client/uploads", consumes = MULTIPART_FORM_DATA_VALUE) List uploadFiles(@RequestPart("files") MultipartFile[] files,@RequestParam("author") String author);}

這個接口定義時候需要有以下注意的幾點(diǎn):

@FeignClient中的value欧漱,對應(yīng)的是服務(wù)實(shí)現(xiàn)類在eureka中注冊的名字,也就是spring.application.name的值

configuration必須配置葬燎,就是咱們上面添加的兩個類误甚,用來編解碼使用

方法可以使用類似Controller中的一些注解,比如方法上可以加@RequestMapping谱净,@PostMapping等窑邦,類上面不可以加,我試的時候壕探,在class上加了@RequestMapping之后報錯冈钦,項目啟動時候顯示Url報錯,其實(shí)李请,也完全不需要加

接受文件的時候瞧筛,必須是@RequestPart注解,我曾經(jīng)看有文章說导盅,@RequestPart和@RequestParam通用较幌,但是我自己測試并不是這樣

consumes對應(yīng)請求的contentType,必須為:multipart/form-data白翻,此處使用了靜態(tài)導(dǎo)包乍炉。

在傳統(tǒng)Controller中,我本身會經(jīng)常簡寫@RequestParam滤馍,忽略他的value字段岛琼。但是Feign接口中不行,如果這些注解沒有括號中的value那么就會報錯

不支持@RequestBody注解

provider-server

這個項目是最后實(shí)際提供服務(wù)的項目纪蜒,所以必須實(shí)現(xiàn)provider-api接口中的方法衷恭,并且注冊到eureka服務(wù)中。

添加對feign的依賴纯续,添加api項目的依賴随珠,其他依賴略

compileproject(":provider-api")"org.springframework.cloud:spring-cloud-starter-feign:$feignVersion"

實(shí)現(xiàn)provider-api中ProviderClient接口灭袁,生成實(shí)現(xiàn)類,并編寫業(yè)務(wù)代碼窗看,需要注意兩點(diǎn)

因為父級已經(jīng)在方法上增加了@PostMapping茸歧,此處可以省略

如果是通過IDEA快生成的實(shí)現(xiàn)類,那么參數(shù)前面的@RequestPart显沈、@RequestParam的注解需要加上软瞎,不然報錯

consumer-server

這個項目是消費(fèi)對方提供服務(wù)的項目,需要做的也比較簡單拉讯。

添加provider-api的項目依賴涤浇,正式環(huán)境下,兩個項目可能是不同組開發(fā)的魔慷,所以需要引入jar包只锭,而不是直接編譯此工程,這里僅做展示使用

compileproject(":provider-api")

在啟動類上增加注解院尔,掃描添加Feign功能對應(yīng)的包

@SpringCloudApplication// 這個注解非常重要蜻展,不然引用不到client中的方法@EnableFeignClients("com.shiyajian.examples.provider")public class ConsumerApplication {publicstaticvoidmain(String[] args) {SpringApplication.run(ConsumerApplication.class); }}

在需要的地方通過@Autowird方式注入,然后就可以進(jìn)行調(diào)用了

@AutowiredProviderClient providerClient;……providerClient.dosomething();……

總結(jié)

? 整個通過Feign-Form上傳文件的案例就寫完了邀摆,第一次寫博客纵顾,寫的不好還望見諒,如果文章解釋的不夠清楚栋盹,可以參考我的項目中的代碼施逾,代碼上可能會更清晰點(diǎn),代碼我已經(jīng)測試通過的贞盯,可以放心使用音念。文章中如果有寫錯誤的地方還望各位指正,當(dāng)然躏敢,如果有什么好的建議也可以給我評論和留言闷愤,如果你還其他關(guān)于java方面的教程和示例代碼你也可以告訴我,我如果不忙的時候件余,我就會寫出來讥脐。

意外

? 在發(fā)文章之前又做了一次測試,這次測試沒有通過啼器,通過調(diào)查發(fā)現(xiàn)旬渠,Eureka中項目的注冊地址變成了:MacBook-Pro.local:provider-server:8100,然后調(diào)用時候就發(fā)生url錯誤端壳,請求fe80:0:0:0:***:8100這個地址告丢,等重新聯(lián)網(wǎng)之后再次啟動,注冊地址就變成 192.168.1.101這種地址损谦。

文章發(fā)布在github上沒有問題岖免,在園子里面出現(xiàn)了格式BUG岳颇,調(diào)了好長時間沒調(diào)好, 就先這樣將就著看吧颅湘。猜測原因是小標(biāo)題后面帶個代碼塊樣式就被頂跑了话侧,但是不知道怎么處理,剛開始用Markdown闯参,以后再研究吧瞻鹏,見諒見諒。

其他

? QQ群:810309655是我的個人好友群鹿寨,主要就是吹牛侃大山新博,順便學(xué)習(xí)技術(shù)共同進(jìn)步。歡迎各種浪的飛起释移、悶騷到爆的同志來玩叭披,但是不歡迎裝逼的。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末玩讳,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子嚼贡,更是在濱河造成了極大的恐慌熏纯,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件粤策,死亡現(xiàn)場離奇詭異樟澜,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)叮盘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門秩贰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人柔吼,你說我怎么就攤上這事毒费。” “怎么了愈魏?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵觅玻,是天一觀的道長。 經(jīng)常有香客問我培漏,道長溪厘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任牌柄,我火速辦了婚禮畸悬,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘珊佣。我一直安慰自己蹋宦,他們只是感情好披粟,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著妆档,像睡著了一般僻爽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上贾惦,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天胸梆,我揣著相機(jī)與錄音,去河邊找鬼须板。 笑死碰镜,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的习瑰。 我是一名探鬼主播绪颖,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼甜奄!你這毒婦竟也來了柠横?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤课兄,失蹤者是張志新(化名)和其女友劉穎牍氛,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體烟阐,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡搬俊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蜒茄。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片唉擂。...
    茶點(diǎn)故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖檀葛,靈堂內(nèi)的尸體忽然破棺而出玩祟,到底是詐尸還是另有隱情,我是刑警寧澤驻谆,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布卵凑,位于F島的核電站,受9級特大地震影響胜臊,放射性物質(zhì)發(fā)生泄漏勺卢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一象对、第九天 我趴在偏房一處隱蔽的房頂上張望黑忱。 院中可真熱鬧,春花似錦、人聲如沸甫煞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽抚吠。三九已至常潮,卻和暖如春楷力,著一層夾襖步出監(jiān)牢的瞬間喊式,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工萧朝, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留岔留,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓检柬,卻偏偏與公主長得像献联,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子何址,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理里逆,服務(wù)發(fā)現(xiàn),斷路器用爪,智...
    卡卡羅2017閱讀 134,656評論 18 139
  • ?通過前面兩章對Spring Cloud Ribbon和Spring Cloud Hystrix的介紹运悲,我們已經(jīng)掌...
    Chandler_玨瑜閱讀 213,053評論 15 140
  • 微服務(wù)架構(gòu)模式的核心在于如何識別服務(wù)的邊界,設(shè)計出合理的微服務(wù)项钮。但如果要將微服務(wù)架構(gòu)運(yùn)用到生產(chǎn)項目上,并且能夠發(fā)揮...
    java菜閱讀 2,949評論 0 6
  • 1 為什么需要服務(wù)發(fā)現(xiàn) 簡單來說希停,服務(wù)化的核心就是將傳統(tǒng)的一站式應(yīng)用根據(jù)業(yè)務(wù)拆分成一個一個的服務(wù)烁巫,而微服務(wù)在這個基...
    謙小易閱讀 25,094評論 4 93
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,810評論 6 342