spring cloud实战与思考(二) 微服务之间通过fiegn上传多个文件1
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了spring cloud实战与思考(二) 微服务之间通过fiegn上传多个文件1,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4725字,纯文字阅读大概需要7分钟。
内容图文
需求场景:
- 微服务之间调用接口一次性上传多个文件。
- 上传文件的同时附带其他参数。
- 多个文件能有效的区分开,以便进行不同处理。
Spring cloud的微服务之间接口调用使用Feign。原装的Feign不支持文件的传输。需要借助“Feign-form”库才行。但是貌似“Feign-form”库(至少是3.0.3版本)只支持单文件上传。在接口中使用多文件参数时会报异常:
feign.codec.EncodeException: class [Lorg.springframework.web.multipart.MultipartFile; is not a type supported by this encoder. at feign.codec.Encoder$Default.encode(Encoder.java:90) ~[feign-core-9.5.0.jar:na] at feign.form.FormEncoder.encode(FormEncoder.java:87) ~[feign-form-3.0.3.jar:3.0.3] at feign.form.spring.SpringFormEncoder.encode(SpringFormEncoder.java:62) ~[feign-form-spring-3.0.3.jar:3.0.3] at feign.ReflectiveFeign$BuildEncodedTemplateFromArgs.resolve(ReflectiveFeign.java:351) ~[feign-core-9.5.0.jar:na] at feign.ReflectiveFeign$BuildTemplateByResolvingArgs.create(ReflectiveFeign.java:213) ~[feign-core-9.5.0.jar:na] at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:72) ~[feign-core-9.5.0.jar:na] at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103) ~[feign-core-9.5.0.jar:na] at com.sun.proxy.$Proxy96.insertWithFiles(Unknown Source) ~[na:na]
在网上搜索一番后,参考博客“https://blog.csdn.net/ytzzh0726/article/details/79467843”,将”Feign-form”库中的”SpringFormEncoder”类改动一下,就可以支持多文件的上传。下面是具体实现方法:
微服务提供方Controller接口:
@ResponseBody @RequestMapping(value="/psts/add/insertWithFiles", method = RequestMethod.POST) public Object insertWithFiles(@RequestParam("baseInfo") String baseInfo, @RequestPart(value = "files") MultipartFile[] photoFiles) { }
服务消费方pom引用Feign-form依赖:
<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> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.3</version> </dependency>
服务消费方声明一个“FeignSpringFormEncoder”类(这个类copy自”SpringFormEncoder”接口):
import feign.RequestTemplate; import feign.codec.EncodeException; import feign.codec.Encoder; import feign.form.ContentType; import feign.form.FormEncoder; import feign.form.MultipartFormContentProcessor; import feign.form.spring.SpringManyMultipartFilesWriter; import feign.form.spring.SpringSingleMultipartFileWriter; import org.springframework.web.multipart.MultipartFile; import java.lang.reflect.Type; import java.util.Collections; import java.util.Map; public class FeignSpringFormEncoder extends FormEncoder { public FeignSpringFormEncoder() { this(new Default()); } public FeignSpringFormEncoder(Encoder delegate) { super(delegate); MultipartFormContentProcessor processor = (MultipartFormContentProcessor)this.getContentProcessor(ContentType.MULTIPART); processor.addWriter(new SpringSingleMultipartFileWriter()); processor.addWriter(new SpringManyMultipartFilesWriter()); } publicvoid encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException { //注释掉原来的代码 // if (!bodyType.equals(MultipartFile.class)) { // super.encode(object, bodyType, template); // } else { // MultipartFile file = (MultipartFile)object; // Map<String, Object> data = Collections.singletonMap(file.getName(), object); // super.encode(data, MAP_STRING_WILDCARD, template); // } //修改为下面的代码if (bodyType.equals(MultipartFile.class)) { MultipartFile file = (MultipartFile) object; Map<String, Object> data = Collections.singletonMap(file.getName(), object); super.encode(data, MAP_STRING_WILDCARD, template); return; } elseif (bodyType.equals(MultipartFile[].class)) { MultipartFile[] file = (MultipartFile[]) object; if(file != null) { Map<String, Object> data = Collections.singletonMap(“files”, object); super.encode(data, MAP_STRING_WILDCARD, template); return; } } super.encode(object, bodyType, template); } }
将“FeignSpringFormEncoder”作为bean提供给框架,代替“SpringFormEncoder”的“encode()”接口:
@Configuration public class FeignMultipartSupportConfig { @Bean @Primary @Scope("prototype") public Encoder multipartFormEncoder() { // return new SpringFormEncoder();returnnew FeignSpringFormEncoder(); } @Bean public feign.Logger.Level multipartLoggerLevel() { return feign.Logger.Level.FULL; } }
以上方案测试可行。到目前为止需求1“多文件上传”和需求2“非文件类型参数上传”都已经满足了。下面来看看怎么对文件数组中的文件进行区分。服务提供方接收到的“MultipartFile”有两个接口“getName()”和“getOriginalFilename()”分别对应文件在http头的“Metadata”名称和文件原始名称。因为使用文件数组上传的功能,前一个名称被固定为“files”,不能用于区分文件。看来只能通过对文件原始名称进行约定来区分文件。但是如果这些文件是用户上传的,这就要求用户上传文件前对文件名称按照约定修改。显然这种接口方式对用户很不友好。限于篇幅,下一篇微博来探讨一下这个问题的解决方法。
原文:https://www.cnblogs.com/standup/p/9090113.html
内容总结
以上是互联网集市为您收集整理的spring cloud实战与思考(二) 微服务之间通过fiegn上传多个文件1全部内容,希望文章能够帮你解决spring cloud实战与思考(二) 微服务之间通过fiegn上传多个文件1所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。