精讲RestTemplate第6篇-文件上传下载与大文件流式下载
本文是精讲RestTemplate第6篇,前篇的blog访问地址如下:
- 精讲RestTemplate第1篇-在Spring或非Spring环境下如何使用
- 精讲RestTemplate第2篇-多种底层HTTP客户端类库的切换
- 精讲RestTemplate第3篇-GET请求使用方法详解
- 精讲RestTemplate第4篇-POST请求方法使用详解
- 精讲RestTemplate第5篇-DELETE、PUT等请求方法使用详解
RestTemplate是HTTP客户端库,所以为了使用RestTemplate进行文件上传和下载,需要我们先编写服务端的支持文件上传和下载的程序。请参考我之前写的一篇文章:SpringBoot实现本地存储文件上传及提供HTTP访问服务 。按照此文完成学习之后,可以获得
- 一个以访问服务URI为"/upload”的文件上传服务端点
- 服务端点上传文件成功后会返回一个HTTP连接,可以用来下载文件。
下面我们就开始学习使用RestTemplate是HTTP客户端库,进行文件的上传与下载。
一、文件上传
写一个单元测试类,来完成RestTemplate文件上传功能,具体实现细节参考代码注释
@SpringBootTest
class UpDownLoadTests {
@Resource
private RestTemplate restTemplate;
@Test
void testUpload() {
// 文件上传服务上传接口
String url = "http://localhost:8888/upload";
// 待上传的文件(存在客户端本地磁盘)
String filePath = "D:\\data\\local\\splash.png";
// 封装请求参数
FileSystemResource resource = new FileSystemResource(new File(filePath));
MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
param.add("uploadFile", resource); //服务端MultipartFile uploadFile
//param.add("param1", "test"); //服务端如果接受额外参数,可以传递
// 发送请求并输出结果
System.out.println("--- 开始上传文件 ---");
String result = restTemplate.postForObject(url, param, String.class);
System.out.println("--- 访问地址:" + result);
}
}
输出结果如下:
--- 开始上传文件 ---
--- 访问地址:http://localhost:8888/2020/08/12/028b38f1-3f9b-4088-9bea-1af8c18cd619.png
文件上传之后,可以通过上面的访问地址,在浏览器访问。或者通过RestTemplate客户端进行下载。
二、文件下载
执行下列代码之后,被下载文件url,会被正确的保存到本地磁盘目录targetPath。
@Test
void testDownLoad() throws IOException {
// 待下载的文件地址
String url = "http://localhost:8888/2020/08/12/028b38f1-3f9b-4088-9bea-1af8c18cd619.png";
ResponseEntity<byte[]> rsp = restTemplate.getForEntity(url, byte[].class);
System.out.println("文件下载请求结果状态码:" + rsp.getStatusCode());
// 将下载下来的文件内容保存到本地
String targetPath = "D:\\data\\local\\splash-down.png";
Files.write(Paths.get(targetPath), Objects.requireNonNull(rsp.getBody(),
"未获取到下载文件"));
}
这种下载方法实际上是将下载文件一次性加载到客户端本地内存,然后从内存将文件写入磁盘。这种方式对于小文件的下载还比较适合,如果文件比较大或者文件下载并发量比较大,容易造成内存的大量占用,从而降低应用的运行效率。
三、大文件下载
这种下载方式的区别在于
- 设置了请求头APPLICATION_OCTET_STREAM,表示以流的形式进行数据加载
- RequestCallback 结合File.copy保证了接收到一部分文件内容,就向磁盘写入一部分内容。而不是全部加载到内存,最后再写入磁盘文件。
@Test
void testDownLoadBigFile() throws IOException {
// 待下载的文件地址
String url = "http://localhost:8888/2020/08/12/028b38f1-3f9b-4088-9bea-1af8c18cd619.png";
// 文件保存的本地路径
String targetPath = "D:\\data\\local\\splash-down-big.png";
//定义请求头的接收类型
RequestCallback requestCallback = request -> request.getHeaders()
.setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL));
//对响应进行流式处理而不是将其全部加载到内存中
restTemplate.execute(url, HttpMethod.GET, requestCallback, clientHttpResponse -> {
Files.copy(clientHttpResponse.getBody(), Paths.get(targetPath));
return null;
});
}
欢迎关注我的博客,里面有很多精品合集
- 本文转载注明出处(必须带连接,不能只转文字):字母哥博客。
觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力! 。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。
- 《手摸手教你学Spring Boot2.0》
- 《Spring Security-JWT-OAuth2一本通》
- 《实战前后端分离RBAC权限管理系统》
- 《实战SpringCloud微服务从青铜到王者》
- 《VUE深入浅出系列》
精讲RestTemplate第6篇-文件上传下载与大文件流式下载的更多相关文章
- 精讲RestTemplate第7篇-自定义请求失败异常处理
本文是精讲RestTemplate第7篇,前篇的blog访问地址如下: 精讲RestTemplate第1篇-在Spring或非Spring环境下如何使用 精讲RestTemplate第2篇-多种底层H ...
- 精讲RestTemplate第8篇-请求失败自动重试机制
本文是精讲RestTemplate第8篇,前篇的blog访问地址如下: 精讲RestTemplate第1篇-在Spring或非Spring环境下如何使用 精讲RestTemplate第2篇-多种底层H ...
- 精讲RestTemplate第9篇-如何通过HTTP Basic Auth认证
本文是精讲RestTemplate第9篇,前篇的blog访问地址如下: 精讲RestTemplate第1篇-在Spring或非Spring环境下如何使用 精讲RestTemplate第2篇-多种底层H ...
- 精讲RestTemplate第10篇-使用代理作为跳板发送请求
本文是精讲RestTemplate第10篇,前篇的blog访问地址如下: 精讲RestTemplate第1篇-在Spring或非Spring环境下如何使用 精讲RestTemplate第2篇-多种底层 ...
- 精讲RestTemplate第3篇-GET请求使用方法详解
本文是精讲RestTemplate第3篇,前篇的blog访问地址如下: 精讲RestTemplate第1篇-在Spring或非Spring环境下如何使用 精讲RestTemplate第2篇-多种底层H ...
- 精讲RestTemplate第4篇-POST请求方法使用详解
本文是精讲RestTemplate第4篇,前篇的blog访问地址如下: 精讲RestTemplate第1篇-在Spring或非Spring环境下如何使用 精讲RestTemplate第2篇-多种底层H ...
- 精讲RestTemplate第4篇-DELETE、PUT等请求方法使用详解
本文是精讲RestTemplate第5篇,前篇的blog访问地址如下: 精讲RestTemplate第1篇-在Spring或非Spring环境下如何使用 精讲RestTemplate第2篇-多种底层H ...
- 精讲RestTemplate第2篇-多种底层HTTP客户端类库的切换
本文是精讲RestTemplate第2篇,前篇的blog访问地址如下: 精讲RestTemplate第1篇-在Spring或非Spring环境下如何使用 RestTemplate只是对其他的HTTP客 ...
- php 文件上传后缀名与文件类型对照表(几乎涵盖所有文件)
网上有很多php文件上传的类,文件上传处理是php的一个特色(至少手册上是将此作为php特点来展示的,个人认为php在数组方面的优异功能更有特 色),学php的人都知道文件上传怎么做,但很多人在编程中 ...
随机推荐
- vue : 本地调试跨域问题的解决办法:proxyTable
本来我是不想写的,但为了加深印象还是写一写吧. ./config/index.js module.exports = { dev: { // Paths assetsSubDirectory: 'st ...
- idea 导入eclipse play1.2.7项目
1.play eclipsify #myapp 转为eclipse目录结构 2.导入eclipse,一路next. 3.新增个Application -Xms1536m-Xmx2048m-Xdebug ...
- 按钮放到图片上,z-index和绝对定位
说明: 最近在做一个banner轮播图 图的左下方有个 登录的按钮. 按钮死活都放不到图片上边,css太菜 特此记录一下 摆放下效果: 无论 轮播图怎么动 按钮不动 思路: 布局 banner轮 ...
- [leetcode/lintcode 题解] Amazon面试题:连接棒材的最低费用
为了装修新房,你需要加工一些长度为正整数的棒材 sticks. 如果要将长度分别为 X 和 Y 的两根棒材连接在一起,你需要支付 X + Y 的费用. 由于施工需要,你必须将所有棒材连接成一根. 返回 ...
- Bug -- WebService报错(两个类具有相同的 XML 类型名称 "{http://webService.com/}getPriceResponse"。请使用 @XmlType.name 和 @XmlType.namespace 为类分配不同的名称。)
调用WebService时报错 解决方法: 在提示的两个java文件中加如一行代码namespace = "http://namespace.thats.not.the.same.as.th ...
- SpringMV学习之拦截器的简单使用
一.拦截器介绍 我们知道SpringMVC的拦截器(Interceptor)非常重要,尤其在Web应用中使用非常广泛,其功能类似于过滤器,用于拦截用户请求并作相应的处理.我们使用比较多的场景是系统登陆 ...
- 02_HTML02
学于黑马和传智播客联合做的教学项目 感谢 黑马官网 传智播客官网 微信搜索"艺术行者",关注并回复关键词"软件测试"获取视频和教程资料! b站在线视频 HTML ...
- matpltlib 示例
matplotlib https://matplotlib.org/index.html
- PHP array_map() 函数
实例 将函数作用到数组中的每个值上,每个值都乘以本身,并返回带有新的值的数组: <?phpfunction myfunction($v){return($v*$v);} $a=array(1,2 ...
- ABC E - Active Infants 贪心 dp
LINK:Active Infants 一个快省选的人 还在写ABC(莫名觉得丢人 不过也无所谓了. 首先考虑 随便一个排列 我们考虑一下其是不是最优的 容易发现如果最大值没有在边界上的话我们直接把它 ...