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类型。
Feign实现文件上传下载的更多相关文章
- Struts的文件上传下载
Struts的文件上传下载 1.文件上传 Struts2的文件上传也是使用fileUpload的组件,这个组默认是集合在框架里面的.且是使用拦截器:<interceptor name=" ...
- Android okHttp网络请求之文件上传下载
前言: 前面介绍了基于okHttp的get.post基本使用(http://www.cnblogs.com/whoislcj/p/5526431.html),今天来实现一下基于okHttp的文件上传. ...
- Selenium2学习-039-WebUI自动化实战实例-文件上传下载
通常在 WebUI 自动化测试过程中必然会涉及到文件上传的自动化测试需求,而开发在进行相应的技术实现是不同的,粗略可划分为两类:input标签类(类型为file)和非input标签类(例如:div.a ...
- 艺萌文件上传下载及自动更新系统(基于networkComms开源TCP通信框架)
1.艺萌文件上传下载及自动更新系统,基于Winform技术,采用CS架构,开发工具为vs2010,.net2.0版本(可以很容易升级为3.5和4.0版本)开发语言c#. 本系统主要帮助客户学习基于TC ...
- 艺萌TCP文件上传下载及自动更新系统介绍(TCP文件传输)(一)
艺萌TCP文件上传下载及自动更新系统介绍(TCP文件传输) 该系统基于开源的networkComms通讯框架,此通讯框架以前是收费的,目前已经免费并开元,作者是英国的,开发时间5年多,框架很稳定. 项 ...
- ssh框架文件上传下载
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- SpringMVC——返回JSON数据&&文件上传下载
--------------------------------------------返回JSON数据------------------------------------------------ ...
- 【FTP】FTP文件上传下载-支持断点续传
Jar包:apache的commons-net包: 支持断点续传 支持进度监控(有时出不来,搞不清原因) 相关知识点 编码格式: UTF-8等; 文件类型: 包括[BINARY_FILE_TYPE(常 ...
- NetworkComms 文件上传下载和客户端自动升级(非开源)
演示程序下载地址:http://pan.baidu.com/s/1geVfmcr 淘宝地址:https://shop183793329.taobao.com 联系QQ号:3201175853 许可:购 ...
随机推荐
- python 用字典进行计数的三种常用方法
1.常规方法 初始化一个字典,遍历列表或字符串,如果遍历的值已经存在于字典中,则字典值直接加1,否则,令字典键为当前遍历的值,字典值为1, 代码如下: >>> dic = {} &g ...
- 细谈 Java 匿名内部类 【分别 使用 接口 和 抽象类实现】
1.前言 匿名内部类是什么东西? 没有名字的内部类就是匿名内部类. 什么场景使用? 匿名内部类适合创建那种只需要一次使用的类. 这是个很有用的东西,可想而知,如果不使用匿名内部类,哪些只需要使用一次的 ...
- spring security +MySQL + BCryptPasswordEncoder 单向加密验证 + 权限拦截 --- 心得
1.前言 前面学习了 security的登录与登出 , 但是用户信息 是 application 配置 或内存直接注入进去的 ,不具有实用性,实际上的使用还需要权限管理,有些 访问接口需要某些权限才可 ...
- react中实现css动画
- etcd的raft选取机制
etcd 是一个分布式的k/V存储系统.核心使用了RAFT分布式一致性协议.一致性这个概念,它是指多个服务器在状态达成一致,但是在一个分布式系统中,因为各种意外可能,有的服务器可能会崩溃或变得不可靠, ...
- SYCOJ2205超级百钱百鸡
题目-超级百钱百鸡 (shiyancang.cn) 百钱百鸡的加强版 百钱百鸡的话,因为是有范围,所以挨个挨个尝试即可,确定两个,即可确定第三个. 超级百钱百鸡,通过题目的描述,最后可以得到一个二元的 ...
- HDU 1576 A/B (两种解法)
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1576 分析:等式枚举法,由题意可得:, ,代入 , 得:,把变量 合在一起得: :即满足 为 倍 ...
- MySQL提权之udf提权(获得webshell的情况)
什么是udf提权? MySQL提供了一个让使用者自行添加新的函数的功能,这种用户自行扩展函数的功能就叫udf. 它的提权原理也非常简单!即是利用了root 高权限,创建带有调用cmd的函数的udf.d ...
- 《剑指offer》面试题32 - I. 从上到下打印二叉树
问题描述 从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印. 例如: 给定二叉树: [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 返回 ...
- 博客新手:图片URL的生成
作为一名博客小白,本人是在美化自己的博客时,发现自定义背景等操作需要提供图片的URL,而不是直接上传图片.那么什么是URL呢?我们又该如何获取它呢? 什么是URL 根据维基百科:统一资源定位符(英语: ...