Feign 如何支持进行文件上传

嗨咯大家好,好久没写了,疫情期间在家也变懒了,不想打开电脑,不想学习敲代码。
不过今天在家上了一天班,遇到了一个问题,弄的我解决了四个小时。当然是百度四个小时,哈哈。不说了,进入正题。

一、依赖

    <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>

我这里的feign是9的版本,所以依赖使用的是3.5之前的。如果要使用3.5之后的,feign需要是10之后的版本。


image.png
image.png

官网地址:https://github.com/OpenFeign/feign-form

二、创建FeignConfig(重要)

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;

import feign.codec.Encoder;
import feign.form.spring.SpringFormEncoder;

@Configuration
public class FeignConfig {
    
    @Bean
    @Primary
    @Scope("prototype")
    public Encoder multipartFormEncoder() {
        return new SpringFormEncoder();
    }

    @Bean
    public feign.Logger.Level multipartLoggerLevel() {
        return feign.Logger.Level.FULL;
    }
}

三、创建Client

@FeignClient(name = "需要对接的服务名",configuration = FeignConfig.class)
@Component
public interface UploadFileClient{

@PostMapping(value="/api/gongj/uploadFile",produces = MediaType.APPLICATION_JSON_UTF8_VALUE, 
            consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    String uploadFile(@RequestPart("multipartFile") MultipartFile multipartFile,@RequestParam("title") String title);
}

四、Controller

    @PostMapping("/uploadFile")
    public ResultVo<String> uploadFile(@RequestParam("title") String title){
        String result = xxxService.uploadFile(title);
        return result;
    }

五、Service

        @Autowired
    UploadFileClient uploadFileClient;

public ResultVo<String> uploadFile(String title) {
            File file = new File("D:\\ee\\审核表.pdf");
        MultipartFile multipartFile = FileUtil.fileToMultipartFile(file);
        String result = uploadFileClient.uploadFile(multipartFile, title);
        return result;
    }

由于我们这块文件是由后台产生的,所以需要将File转换为MultipartFile。如果是前台传入的,就不需要转了。

六、加入新依赖

<dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.3</version>
        </dependency>

FileUtils

public static MultipartFile fileToMultipartFile(File file) {
        String fieldName = "multipartFile";  //重点  这个名字需要和你对接的MultipartFil的名称一样
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        FileItem item = factory.createItem(fieldName, "multipart/form-data", true, file.getName());
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        try {
            FileInputStream fis = new FileInputStream(file);
            OutputStream os = item.getOutputStream();
            while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new CommonsMultipartFile(item);
    }

这是服务端的代码。


image.png

这是FeignClient的代码。


image.png

这几个地方一定要保持一致,就是这个地方我找了好久。不然会报

Required request part ‘file’ is not present。

补充:

写完之后测试了一下的确支持文件传输了,以为大功告成。不过今天又写了一个接口,需要传递实体的。出现了

is not a type supported by this encoder

又开始百度一番,原来是冲突了,上面那种解决方式不太完美。
参考:https://blog.csdn.net/gududedabai/article/details/79895893
上面博文的方案一就不用试了,那种只适用于只有文件传输的,如果有实体传输那是实现不了的。

修改FeignConfig

import feign.codec.Encoder;
import feign.form.spring.SpringFormEncoder;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration  
public class FeignConfig {  
    @Autowired  
    private ObjectFactory<HttpMessageConverters> messageConverters;  
          
    @Bean  
    public Encoder feignFormEncoder() {  
        return new SpringFormEncoder(new SpringEncoder(messageConverters));  
    }  
 }  
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。