使用Feign进行服务调用上传文件时的采坑记录

    技术2022-07-16  104

    今天在进行文件上传的接口测试中,Feign的对端一直获取不到图片,在排除了Feign配置、契约等错误后,终于在bebug中发现了问题所在。

    注意!!

    在前端第一次将图片上传至后端时,默认的StandardMultipartHttpServletRequest会将形式参数的名字作为MultipartFile中的part属性的name,从而使这个MultipartFile绑定上这个字段,如果Feign所连对端的形参名字与file中的name属性不匹配(即使在requestpart中指定了名字,但是multipart中只有get方法,并无法重新命名),就会导致文件中的内容对端无法接收(或者说传过去了一个和requestpart中指定的名字一样的空的file)

    解决方法

    自己重新实现MultipartFile接口,在构造器中重新对name赋值,文件则用byte数组进行存储,这样转换一下用新建的MultipartFile传输,就可以成功了

    代码环节

    private final String name; private String originalFilename; @Nullable private String contentType; private final byte[] content; public MyMultipartFile(String name, @Nullable byte[] content) { this(name, "", (String)null, (byte[])content); } public MyMultipartFile(String name, InputStream contentStream) throws IOException { this(name, "", (String)null, (byte[])FileCopyUtils.copyToByteArray(contentStream)); } public MyMultipartFile(String name, @Nullable String originalFilename, @Nullable String contentType, @Nullable byte[] content) { Assert.hasLength(name, "Name must not be null"); this.name = name; this.originalFilename = originalFilename != null ? originalFilename : ""; this.contentType = contentType; this.content = content != null ? content : new byte[0]; } public MyMultipartFile(String name, @Nullable String originalFilename, @Nullable String contentType, InputStream contentStream) throws IOException { this(name, originalFilename, contentType, FileCopyUtils.copyToByteArray(contentStream)); } @Override public String getName() { return this.name; } @Override public String getOriginalFilename() { return this.originalFilename; } @Override @Nullable public String getContentType() { return this.contentType; } @Override public boolean isEmpty() { return this.content.length == 0; } @Override public long getSize() { return (long)this.content.length; } @Override public byte[] getBytes() throws IOException { return this.content; } @Override public InputStream getInputStream() throws IOException { return new ByteArrayInputStream(this.content); } @Override public void transferTo(File dest) throws IOException, IllegalStateException { FileCopyUtils.copy(this.content, dest); }

    这样现将multipartFile转换为临时文件,在通过构造器重新转换为multipartFile并写上自己需要的文件名,就可以了。

    Processed: 0.009, SQL: 9