使用Spring Cloud Feign上傳文件的示例
最近經(jīng)常有人問Spring Cloud Feign如何上傳文件。有團隊的新成員,也有其他公司的兄弟。本文簡單做個總結(jié)——
早期的Spring Cloud中,F(xiàn)eign本身是沒有上傳文件的能力的(1年之前),要想實現(xiàn)這一點,需要自己去編寫Encoder 去實現(xiàn)上傳?,F(xiàn)在我們幸福了很多。因為Feign官方提供了子項目feign-form ,其中實現(xiàn)了上傳所需的 Encoder 。
注:筆者測試的版本是Edgware.RELEASE。Camden、Dalston同樣適應(yīng)本文所述。
加依賴
<dependency> <groupId>io.github.openfeign.form</groupId> <artifactId>feign-form</artifactId> <version>3.0.3</version> </dependency> <dependency> <groupId>io.github.openfeign.form</groupId> <artifactId>feign-form-spring</artifactId> <version>3.0.3</version> </dependency>
編寫Feign Client
@FeignClient(name = "ms-content-sample", configuration = UploadFeignClient.MultipartSupportConfig.class) public interface UploadFeignClient { @RequestMapping(value = "/upload", method = RequestMethod.POST, produces = {MediaType.APPLICATION_JSON_UTF8_VALUE}, consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @ResponseBody String handleFileUpload(@RequestPart(value = "file") MultipartFile file); class MultipartSupportConfig { @Bean public Encoder feignFormEncoder() { return new SpringFormEncoder(); } } }
如代碼所示,在這個Feign Client中,我們引用了配置類MultipartSupportConfig ,在MultipartSupportConfig 中,我們實例化了SpringFormEncoder 。這樣這個Feign Client就能夠上傳啦。
注意點
@RequestMapping(value = "/upload", method = RequestMethod.POST, produces = {MediaType.APPLICATION_JSON_UTF8_VALUE}, consumes = MediaType.MULTIPART_FORM_DATA_VALUE) 中的produeces 、consumes 不能少;
接口定義中的注解@RequestPart(value = "file") 不能寫成@RequestParam(value = "file" 。
最好將Hystrix的超時時間設(shè)長一點,例如5秒,否則可能文件還沒上傳完,Hystrix就超時了,從而導(dǎo)致客戶端側(cè)的報錯。
SpringCloud中使用Feign的坑
示例如下:
@FeignClient("service-resource") //@RequestMapping("/api/test") public interface TestResourceItg { @RequestMapping(value = "/api/test/raw", method = RequestMethod.POST, consumes = "application/x-www-form-urlencoded") public String raw1(@PathVariable("subject") String subject, // 標題 @RequestParam("content") String content); // 內(nèi)容 }
說明:
*使用RequestMapping中的consumes指定生成的請求的Content-Type
*RequestParam指定的參數(shù)會拼接在URL之后,如: ?name=xxx&age=18
*PathVariable指定的參數(shù)會放到一個LinkedHashMap<String, ?>傳入到feign的Encoder中進行處理,而在Spring中實現(xiàn)了該接口的Encoder為SpringEncoder,而該實現(xiàn)又會使用Spring中的HttpMessageConverter進行請求體的寫入。
坑:
*不要在接口類名上使用RequestMapping,雖然可以使用,但同時SpringMVC會把該接口的實例當作Controller開放出去,這個可以在啟動的Mapping日志中查看到
*使用默認的SpringEncoder,在不指定consumes時,PathVariable中的參數(shù)會生成JSON字符串發(fā)送,且默認情況下不支持Form表單的生成方式,原因為:FormHttpMessageConverter只能處理MultiValueMap,而使用PathVariable參數(shù)被放在了HashMap中。默認更不支持文件上傳。其實已經(jīng)有支持處理各種情況的HttpMessageConverter存在。
填坑:
*支持Form表單提交:只需要編寫一個支持Map的FormHttpMessageConverter即可,內(nèi)部可調(diào)用FormHttpMessageConverter的方法簡化操作。
*支持文件上傳:只需要把要上傳的文件封裝成一個Resource(該Resource一定要實現(xiàn)filename接口,這個是把請求參數(shù)解析成文件的標識),使用默認的ResourceHttpMessageConverter處理即可。
*支持處理MultipartFile參數(shù):編寫一個支持MultipartFile的MultipartFileHttpMessageConverter即可,內(nèi)部可調(diào)用ResourceHttpMessageConverter實現(xiàn),同時注意需要將其添加至FormHttpMessageConverter的Parts中,并重寫FormHttpMessageConverter的getFilename方法支持從MultipartFile中獲取filename
*所有的HttpMessageConverter直接以@Bean的方式生成即可,spring會自動識別添加
完美支持表單和文件上傳:
方案一:
使用附件中的MapFormHttpMessageConverter.java和MultipartFileHttpMessageConverter.java
在Spring中進行如下配置即可
@Bean public MapFormHttpMessageConverter mapFormHttpMessageConverter(MultipartFileHttpMessageConverter multipartFileHttpMessageConverter) { MapFormHttpMessageConverter mapFormHttpMessageConverter = new MapFormHttpMessageConverter(); mapFormHttpMessageConverter.addPartConverter(multipartFileHttpMessageConverter); return mapFormHttpMessageConverter; } @Bean public MultipartFileHttpMessageConverter multipartFileHttpMessageConverter() { return new MultipartFileHttpMessageConverter(); }
方案二:
使用FeignSpringFormEncoder.java
在Spring中配置如下:
@Bean public Encoder feignEncoder(ObjectFactory<HttpMessageConverters> messageConverters) { return new FeignSpringFormEncoder(messageConverters); }
推薦使用方案一
方案二為參考https://github.com/pcan/feign-client-test而來,未測
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Linux中使用shell腳本管理Java應(yīng)用程序
在日常開發(fā)和運維工作中,管理基于Java的應(yīng)用程序是一項基礎(chǔ)且頻繁的任務(wù),本文將通過一個示例腳本,展示如何利用Shell腳本簡化這一流程,實現(xiàn)Java應(yīng)用的一鍵式啟動、停止與重啟操作,本腳本不僅提升了工作效率,還確保了操作的標準化與可靠性2024-06-06Springboot整合PageOffice 實現(xiàn)word在線編輯保存功能
這篇文章主要介紹了Springboot整合PageOffice 實現(xiàn)word在線編輯保存,本文以Samples5 為示例文件結(jié)合示例代碼給大家詳細介紹,需要的朋友可以參考下2021-08-08java多線程之wait(),notify(),notifyAll()的詳解分析
本篇文章是對java多線程 wait(),notify(),notifyAll()進行了詳細的分析介紹,需要的朋友參考下2013-06-06Spring Security角色繼承實現(xiàn)過程解析
這篇文章主要介紹了Spring Security角色繼承實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-08-08mybatis-plus之如何實現(xiàn)in嵌套sql
這篇文章主要介紹了mybatis-plus之如何實現(xiàn)in嵌套sql問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03