这期内容当中小编将会给大家带来有关怎么在Spring Cloud中使用FeignClient实现文件上传功能,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
具体的使用方法是加入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接口里方法参数是文件类型的要用@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);
但遇到一个问题,就是不支持文件数组类型,我看了源码,发现源码里底层是有对MultipartFile[]类型的支持的,源码中有个类叫SpringManyMultipartFilesWriter,是专门针对文件数组类型进行操作的,但是配置到项目里的SpringFormEncoder类里却没有对文件数组类型的判断,以致不能支持文件数组的上传.。
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类型,没有判断数组类型,这就比较奇怪了,底层有对数组的支持但上层却缺少了相应判断,而且在源码里的test包里也没有对文件数组类型的测试,难道只是encode方法里漏掉了?还是说那个文件数组的支持有问题?所以encode方法里才没有加入对其的判断?
于是我先试着对encode方法进行扩展加入对文件数组的判断,应该就可以支持文件数组的上传了,于是把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); } }
上述就是小编为大家分享的怎么在Spring Cloud中使用FeignClient实现文件上传功能了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。