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-formfeign-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类型。

Feign实现文件上传下载的更多相关文章

  1. Struts的文件上传下载

    Struts的文件上传下载 1.文件上传 Struts2的文件上传也是使用fileUpload的组件,这个组默认是集合在框架里面的.且是使用拦截器:<interceptor name=" ...

  2. Android okHttp网络请求之文件上传下载

    前言: 前面介绍了基于okHttp的get.post基本使用(http://www.cnblogs.com/whoislcj/p/5526431.html),今天来实现一下基于okHttp的文件上传. ...

  3. Selenium2学习-039-WebUI自动化实战实例-文件上传下载

    通常在 WebUI 自动化测试过程中必然会涉及到文件上传的自动化测试需求,而开发在进行相应的技术实现是不同的,粗略可划分为两类:input标签类(类型为file)和非input标签类(例如:div.a ...

  4. 艺萌文件上传下载及自动更新系统(基于networkComms开源TCP通信框架)

    1.艺萌文件上传下载及自动更新系统,基于Winform技术,采用CS架构,开发工具为vs2010,.net2.0版本(可以很容易升级为3.5和4.0版本)开发语言c#. 本系统主要帮助客户学习基于TC ...

  5. 艺萌TCP文件上传下载及自动更新系统介绍(TCP文件传输)(一)

    艺萌TCP文件上传下载及自动更新系统介绍(TCP文件传输) 该系统基于开源的networkComms通讯框架,此通讯框架以前是收费的,目前已经免费并开元,作者是英国的,开发时间5年多,框架很稳定. 项 ...

  6. ssh框架文件上传下载

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. SpringMVC——返回JSON数据&&文件上传下载

    --------------------------------------------返回JSON数据------------------------------------------------ ...

  8. 【FTP】FTP文件上传下载-支持断点续传

    Jar包:apache的commons-net包: 支持断点续传 支持进度监控(有时出不来,搞不清原因) 相关知识点 编码格式: UTF-8等; 文件类型: 包括[BINARY_FILE_TYPE(常 ...

  9. NetworkComms 文件上传下载和客户端自动升级(非开源)

    演示程序下载地址:http://pan.baidu.com/s/1geVfmcr 淘宝地址:https://shop183793329.taobao.com 联系QQ号:3201175853 许可:购 ...

随机推荐

  1. sublime text 3 添加packagecontrol

    打开sublime控制台输入 import urllib.request,os,hashlib; h = '6f4c264a24d933ce70df5dedcf1dcaee' + 'ebe013ee1 ...

  2. Python爬取中国知网文献、参考文献、引证文献

    前两天老师派了个活,让下载知网上根据高级搜索得到的来源文献的参考文献及引证文献数据,网上找了一些相关博客,感觉都不太合适,因此特此记录,希望对需要的人有帮助. 切入正题,先说这次需求,高级搜索,根据中 ...

  3. Hive分析统计离线日志信息

    关注公众号:分享电脑学习回复"百度云盘" 可以免费获取所有学习文档的代码(不定期更新)云盘目录说明:tools目录是安装包res 目录是每一个课件对应的代码和资源等doc 目录是一 ...

  4. 通过js触发launch事件获取页面信息

    注:图片如果损坏,点击文章链接:https://www.toutiao.com/i6814776265602499080/ 承接上一篇文档<页面Cookie的JS文件编写> 思路 继续之前 ...

  5. vue使用npm安装sass

    npm install --save-dev sass-loader style-loader css-loader npm install --save-dev extract-text-webpa ...

  6. test_4 实现一个统计函数运行时间

    1.datetime显示当前时间 import datetimeimport timedef func(): t = datetime.datetime.now() print t print &qu ...

  7. kafka时间轮简易实现(二)

    概述 上一篇主要介绍了kafka时间轮源码和原理,这篇主要介绍一下kafka时间轮简单实现和使用kafka时间轮.如果要实现一个时间轮,就要了解他的数据结构和运行原理,上一篇随笔介绍了不同种类的数据结 ...

  8. Java反射给泛型集合赋值

    Java反射给泛型集合赋值 泛型 Java泛型简单描述下: 比如创建一个List集合,我想在里边只放Student对象信息,就需要写成 List<Student> studentList ...

  9. 【刷题-LeetCode】300. Longest Increasing Subsequence

    Longest Increasing Subsequence Given an unsorted array of integers, find the length of longest incre ...

  10. 【刷题-LeetCode】153 Find Minimum in Rotated Sorted Array

    Find Minimum in Rotated Sorted Array Suppose an array sorted in ascending order is rotated at some p ...