Spring Cloud Feign實現文件上傳下載的示例代碼

 Feign框架對於文件上傳消息體格式並沒有做原生支持,需要集成模塊feign-form來實現。

獨立使用Feign

添加模塊依賴:

<!-- Feign框架核心 -->
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-core</artifactId>
    <version>11.1</version>
</dependency>
<!-- 支持表單格式,文件上傳格式 -->
<dependency>
    <groupId>io.github.openfeign.form</groupId>
    <artifactId>feign-form</artifactId>
    <version>3.8.0</version>
</dependency>
<!-- 文件操作工具類 -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.11.0</version>
</dependency>

上傳文件

定義接口:

public interface FileUploadAPI {
    // 上傳文件:參數為單個文件對象
    @RequestLine("POST /test/upload/single")
    @Headers("Content-Type: multipart/form-data")
    String upload(@Param("file") File file);

    // 上傳文件:參數文多個文件對象
    @RequestLine("POST /test/upload/batch")
    @Headers("Content-Type: multipart/form-data")
    String upload(@Param("files") File[] files);

    // 上傳文件:參數文多個文件對象
    @RequestLine("POST /test/upload/batch")
    @Headers("Content-Type: multipart/form-data")
    String upload(@Param("files") List<File> files);

    // 上傳文件:參數為文件字節數組(這種方式在服務端無法獲取文件名,不要使用)
    @RequestLine("POST /test/upload/single")
    @Headers("Content-Type: multipart/form-data")
    String upload(@Param("file") byte[] bytes);

    // 上傳文件:參數為FormData對象
    @RequestLine("POST /test/upload/single")
    @Headers("Content-Type: multipart/form-data")
    String upload(@Param("file") FormData photo);

    // 上傳文件:參數為POJO對象
    @RequestLine("POST /test/upload/single")
    @Headers("Content-Type: multipart/form-data")
    String upload(@Param("file") MyFile myFile);

    class MyFile {
        @FormProperty("is_public")
        Boolean isPublic;
        File file;

        public Boolean getPublic() {
            return isPublic;
        }

        public void setPublic(Boolean aPublic) {
            isPublic = aPublic;
        }

        public File getFile() {
            return file;
        }

        public void setFile(File file) {
            this.file = file;
        }
    }
}

調用接口:

FileAPI fileAPI = Feign.builder()
        .encoder(new FormEncoder()) // 必須明確設置請求參數編碼器
        .logger(new Slf4jLogger())
        .logLevel(Logger.Level.FULL)
        .target(FileAPI.class, "http://localhost:8080");
File file1 = new File("C:\\Users\\xxx\\Downloads\\test1.jpg");
File file2 = new File("C:\\Users\\xxx\\Downloads\\test2.jpg");

// 上傳文件1:參數為文件對象
fileAPI.upload(file1);

// 上傳文件2:參數為字節數組(註意:在服務端無法獲取到文件名)
byte[] bytes = FileUtils.readFileToByteArray(file1);
fileAPI.upload(bytes);

// 上傳文件3:參數為FormData對象
byte[] bytes = FileUtils.readFileToByteArray(file1);
FormData formData = new FormData("image/jpg", "test1.jpg", bytes);
String result = fileAPI.upload(formData);

// 上傳文件4:參數為POJO對象
FileAPI.MyFile myFile = new FileAPI.MyFile();
myFile.setPublic(true);
myFile.setFile(file1);
fileAPI.upload(myFile);

// 上傳文件:參數為多個文件
fileAPI.upload(new File[]{file1, file2});
fileAPI.upload(Arrays.asList(new File[]{file1, file2}));

下載文件

定義接口:

public interface FileDownloadAPI {
    // 下載文件
    @RequestLine("GET /test/download/file")
    Response download(@QueryMap Map<String, Object> queryMap);
}

調用接口:

// 下載文件時返回值為Response對象,不需要設置解碼器
FileAPI fileAPI = Feign.builder()
                .logger(new Slf4jLogger())
                .logLevel(Logger.Level.FULL)
                .target(FileAPI.class, "http://localhost:8080");
String fileName = "test.jpg";
Map<String, Object> queryMap = new HashMap<>();
queryMap.put("fileName", fileName);
Response response = fileAPI.download(queryMap);
if (response.status() == 200) {
    File downloadFile = new File("D:\\Downloads\\", fileName);
    FileUtils.copyInputStreamToFile(response.body().asInputStream(), downloadFile);
}

使用Spring Cloud Feign

在Spring框架中使用Feign實現文件上傳時需要依賴feign-form和feign-form-spring,這2個模塊已經在“Spring Cloud Feign”中自帶瞭,隻需要添加spring-cloud-starter-openfeign依賴即可。

<!-- 集成Spring和Feign,包含瞭模塊feign-form和feign-form-spring -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <version>3.0.2</version>
</dependency>

<!-- 文件操作工具類 -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.11.0</version>
</dependency>

上傳文件

定義接口及配置:

@FeignClient(value = "FileAPI", url = "http://localhost:8080", configuration = FileUploadAPI.FileUploadAPIConfiguration.class)
public interface FileUploadAPI {

    /**
     * 上傳單個文件
     * @param file
     * @return
     */
    @RequestMapping(value = "/test/upload/single", method = RequestMethod.POST, headers = "Content-Type=multipart/form-data")
    String upload(@RequestPart("file") MultipartFile file);

    /**
     * 上傳多個文件
     * @param files
     * @return
     */
    @RequestMapping(value = "/test/upload/batch", method = RequestMethod.POST, headers = "Content-Type=multipart/form-data")
    String upload(@RequestPart("files") List<MultipartFile> files);

    class FileUploadAPIConfiguration {
        @Autowired
        private ObjectFactory<HttpMessageConverters> messageConverters;

        @Bean
        public Encoder feignEncoder () {
            return new SpringFormEncoder(new SpringEncoder(messageConverters));
        }

        @Bean
        public Logger feignLogger() {
            return new Slf4jLogger();
        }

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

調用接口:

// 上傳單個文件
File file = new File("C:\\Users\\xxx\\Downloads\\test1.jpg");
FileInputStream fis = new FileInputStream(file);
MockMultipartFile mockMultipartFile = new MockMultipartFile("file", file.getName(), "image/jpg", fis);
this.fileUploadAPI.upload(mockMultipartFile);
fis.close();

// 上傳多個文件
File file1 = new File("C:\\Users\\xxx\\Downloads\\test1.jpg");
File file2 = new File("C:\\Users\\xxx\\Downloads\\test2.jpg");
FileInputStream fis1 = new FileInputStream(file1);
FileInputStream fis2 = new FileInputStream(file2);
MockMultipartFile f1 = new MockMultipartFile("files", file1.getName(), "image/jpg", fis1);
MockMultipartFile f2 = new MockMultipartFile("files", file2.getName(), "image/jpg", fis2);
this.fileUploadAPI.upload(Arrays.asList(new MockMultipartFile[]{f1, f2}));
fis1.close();
fis2.close();

下載文件

定義接口:

@FeignClient(value = "FileDownloadAPI", url = "http://localhost:8080", configuration = FileDownloadAPI.FileDownloadAPIConfiguration.class)
public interface FileDownloadAPI {

    /**
     * 下載文件
     * @param fileName 文件名
     * @return
     */
    @RequestMapping(value = "/test/download/file", method = RequestMethod.GET)
    Response download(@RequestParam("fileName") String fileName);

    // 下載文件時返回值為Response對象,不需要設置解碼器
    class FileDownloadAPIConfiguration {
        @Bean
        public Logger feignLogger() {
            return new Slf4jLogger();
        }

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

調用接口:

String fileName = "test.jpg";
Response response = this.fileDownloadAPI.download(fileName);
File destFile = new File("D:\\Downloads\\", fileName);
// 使用org.apache.commons.io.FileUtils工具類將輸入流中的內容轉存到文件
FileUtils.copyInputStreamToFile(response.body().asInputStream(), destFile);

總結

1.Feign框架需要集成模塊feign-form才能支持文件上傳的消息體格式。
2.不論是獨立使用Feign,還是使用Spring Cloud Feign,下載文件時的返回值都必須為feign.Response類型。

到此這篇關於 Spring Cloud Feign實現文件上傳下載的示例代碼的文章就介紹到這瞭,更多相關 Spring Cloud Feign文件上傳下載內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: