1.使用原因
公司最近做的项目在用SpringCloud,涉及到了上传。但是Feign本身是不支持文件类型的。所以这里把上传下载的实现分享一下。
2.所需配置
这是自己实现的一个formEncoder,可以支持单文件和数组的多文件上传
public class FeignSpringFormEncoder extends FormEncoder { /** * Constructor with the default Feign's encoder as a delegate. */ public FeignSpringFormEncoder() { this(new Default()); } /** * Constructor with specified delegate encoder. * * @param delegate delegate encoder, if this encoder couldn't encode object. */ public FeignSpringFormEncoder(Encoder delegate) { super(delegate); MultipartFormContentProcessor processor = (MultipartFormContentProcessor) getContentProcessor(ContentType.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)) { MultipartFile file = (MultipartFile) object; Map data = Collections.singletonMap(file.getName(), object); super.encode(data, MAP_STRING_WILDCARD, template); return; } else if (bodyType.equals(MultipartFile[].class)) { MultipartFile[] file = (MultipartFile[]) object; if(file != null) { Map data = Collections.singletonMap(file.length == 0 ? "" : file[0].getName(), object); super.encode(data, MAP_STRING_WILDCARD, template); return; } } super.encode(object, bodyType, template); } }
将实现的类注册一下。
@Bean public Encoder feignEncoder(ObjectFactory<HttpMessageConverters> messageConverters) { return new FeignSpringFormEncoder(new SpringEncoder(messageConverters)); }
调用方的代码,这里参数接收的时候用的是@RequestPart,与@RequestParam区别大家可以去查一下。
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @ResponseBody public ApiResult upload(@RequestPart(value = "file") MultipartFile file) { return fileUploadApiClient.upload(file); }
暴露的fileUploadApiClient接口还需要添加依赖
<dependency> <groupId>io.github.openfeign.form</groupId> <artifactId>feign-form</artifactId> <version>3.3.0</version> </dependency> <dependency> <groupId>io.github.openfeign.form</groupId> <artifactId>feign-form-spring</artifactId> <version>3.3.0</version> </dependency>
暴露的fileUploadApiClient代码,MediaType类型的指定
@PostMapping(value = "/oss/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
ApiResult upload(@RequestPart(value = "file") MultipartFile file);
最后直接调用就可以上传成功.