Spring Cloud中FeignClient實現(xiàn)文件上傳功能
項目概況:Spring Cloud搭的微服務,使用了eureka,F(xiàn)eignClient,現(xiàn)在遇到FeignClient調用接口時不支持上傳文件,
百度到兩種方案,一種是使用feign-form和feign-form-spring庫來做,源碼地址。
具體的使用方法是加入maven依賴
<dependency> <groupId>io.github.openfeign.form</groupId> <artifactId>feign-form-spring</artifactId> <version>3.2.2</version> </dependency> <dependency> <groupId>io.github.openfeign.form</groupId> <artifactId>feign-form</artifactId> <version>3.2.2</version> </dependency>
注入SpringFormEncoder類
@Bean @Primary @Scope("prototype") public Encoder multipartFormEncoder() { return new SpringFormEncoder(); }
FeignClient接口里方法參數(shù)是文件類型的要用@RequestPart注解,且要設置ContentType為multipart/form-data
@ResponseBody @RequestMapping(value = "/ctstestcase/updateTestCase", method = {RequestMethod.POST}, consumes = MediaType.MULTIPART_FORM_DATA_VALUE) Map<String, Object> updateTestCase(@RequestParam("testcaseId") String testcaseId, @RequestParam("name") String name, @RequestParam("assignId") String assignId, @RequestParam("areaId") String areaId, @RequestParam("state") Integer state, @RequestParam("iterationId") String iterationId,@RequestParam("priority") Integer priority, @RequestParam("moduleId") String moduleId, @RequestParam("executionType") Integer executionType, @RequestParam("summary") String summary, @RequestParam("tcsteps") String tcsteps, @RequestParam("relations") String relations,@RequestParam("attachments") String attachments, @RequestPart("files") MultipartFile[] files);
但遇到一個問題,就是不支持文件數(shù)組類型,我看了源碼,發(fā)現(xiàn)源碼里底層是有對MultipartFile[]類型的支持的,源碼中有個類叫SpringManyMultipartFilesWriter,是專門針對文件數(shù)組類型進行操作的,但是配置到項目里的SpringFormEncoder類里卻沒有對文件數(shù)組類型的判斷,以致不能支持文件數(shù)組的上傳.。
SpringManyMultipartFilesWriter源碼:
@FieldDefaults(level = PRIVATE, makeFinal = true) public class SpringManyMultipartFilesWriter extends AbstractWriter { SpringSingleMultipartFileWriter fileWriter = new SpringSingleMultipartFileWriter(); @Override public void write (Output output, String boundary, String key, Object value) throws Exception { if (value instanceof MultipartFile[]) { val files = (MultipartFile[]) value; for (val file : files) { fileWriter.write(output, boundary, key, file); } } else if (value instanceof Iterable) { val iterable = (Iterable<?>) value; for (val file : iterable) { fileWriter.write(output, boundary, key, file); } } } @Override public boolean isApplicable (Object value) { if (value == null) { return false; } if (value instanceof MultipartFile[]) { return true; } if (value instanceof Iterable) { val iterable = (Iterable<?>) value; val iterator = iterable.iterator(); if (iterator.hasNext() && iterator.next() instanceof MultipartFile) { return true; } } return false; }
SpringFormEncoder源碼:
public class SpringFormEncoder extends FormEncoder { /** * Constructor with the default Feign's encoder as a delegate. */ public SpringFormEncoder () { this(new Encoder.Default()); } /** * Constructor with specified delegate encoder. * * @param delegate delegate encoder, if this encoder couldn't encode object. */ public SpringFormEncoder (Encoder delegate) { super(delegate); val processor = (MultipartFormContentProcessor) getContentProcessor(MULTIPART); processor.addWriter(new SpringSingleMultipartFileWriter()); processor.addWriter(new SpringManyMultipartFilesWriter()); } @Override public void encode (Object object, Type bodyType, RequestTemplate template) throws EncodeException { if (!bodyType.equals(MultipartFile.class)) { super.encode(object, bodyType, template); return; } val file = (MultipartFile) object; val data = singletonMap(file.getName(), object); super.encode(data, MAP_STRING_WILDCARD, template); } }
從上面SpringFormEncoder的源碼上可以看到SpringFormEncoder類構造時把SpringManyMultipartFilesWriter實例添加到了處理器列表里了,但是在encode方法里又只判斷了MultipartFile類型,沒有判斷數(shù)組類型,這就比較奇怪了,底層有對數(shù)組的支持但上層卻缺少了相應判斷,而且在源碼里的test包里也沒有對文件數(shù)組類型的測試,難道只是encode方法里漏掉了?還是說那個文件數(shù)組的支持有問題?所以encode方法里才沒有加入對其的判斷?
于是我先試著對encode方法進行擴展加入對文件數(shù)組的判斷,應該就可以支持文件數(shù)組的上傳了,于是把SpringFormEncoder類源碼復制出來重命名為FeignSpringFormEncoder,源碼如下:
public class FeignSpringFormEncoder extends FormEncoder { /** * Constructor with the default Feign's encoder as a delegate. */ public FeignSpringFormEncoder() { this(new Encoder.Default()); } /** * Constructor with specified delegate encoder. * * @param delegate delegate encoder, if this encoder couldn't encode object. */ public FeignSpringFormEncoder(Encoder delegate) { super(delegate); val processor = (MultipartFormContentProcessor) getContentProcessor(MULTIPART); processor.addWriter(new SpringSingleMultipartFileWriter()); processor.addWriter(new SpringManyMultipartFilesWriter()); } @Override public void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException { if (bodyType.equals(MultipartFile.class)) { val file = (MultipartFile) object; val data = singletonMap(file.getName(), object); super.encode(data, MAP_STRING_WILDCARD, template); return; } else if (bodyType.equals(MultipartFile[].class)) { val file = (MultipartFile[]) object; if(file != null) { val data = singletonMap(file.length == 0 ? "" : file[0].getName(), object); super.encode(data, MAP_STRING_WILDCARD, template); return; } } super.encode(object, bodyType, template); } }
經過測試,已經可以支持文件數(shù)組了,完美解決。
這里再順便說一下當時還百度到另一個解決文件上傳的方案,這個方案就不細說了,直接上我用到的那個開源代碼的地址
這個我試過也是可以解決文件上傳問題的,但問題是FeignClient不能用SpringMVC的注解,得用Feign自帶的注解,也因此我才擴展了第一種方法來做的文件上傳功能。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
JetBrains IntelliJ IDEA 配置優(yōu)化技巧
這篇文章主要介紹了JetBrains IntelliJ IDEA 配置優(yōu)化技巧,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12使Java的JButton文字隱藏功能的實現(xiàn)(不隱藏按鈕的前提)
這篇文章主要介紹了使Java的JButton文字隱藏功能的實現(xiàn)(不隱藏按鈕的前提),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-01-01Spring ApplicationContextAware 接口的作用及使用方式
Spring提供了許多回調接口,用于Bean生命周期中執(zhí)行特定的操作,通過實現(xiàn)ApplicationContextAware接口,Spring提供了一種便捷的方式讓 Bean獲取對Spring容器的引用,本文介紹ApplicationContextAware接口的作用、使用方式,以及在實際應用中的常見場景,感興趣的朋友一起看看吧2024-01-01tio-boot?jfinal-plugins框架整合redis示例詳解
這篇文章主要為大家介紹了tio-boot?jfinal-plugins框架整合redis示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-12-12SpringBoot面試突擊之過濾器和攔截器區(qū)別詳解
過濾器(Filter)和攔截器(Interceptor)都是基于?AOP(Aspect?Oriented?Programming,面向切面編程)思想實現(xiàn)的,用來解決項目中某一類問題的兩種“工具”,但二者有著明顯的差距,接下來我們一起來看2022-10-10打開.properties中文顯示unicode編碼問題以及解決
這篇文章主要介紹了打開.properties中文顯示unicode編碼問題以及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01