背景
? 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)步。歡迎各種浪的飛起释移、悶騷到爆的同志來玩叭披,但是不歡迎裝逼的。