springBoot 简单优雅是实现文件上传和下载

前言

好久没有更新spring Boot 这个项目了。最近看了一下docker 的知识,后期打算将spring boot 和docker 结合起来。刚好最近有一个上传文件的工作呢,刚好就想起这个脚手架,将文件上传和下载整理进来。

配置

在application.properties 中增加上传文件存放的路径配置

#文件上传目录
file.upload.url=E:/test

controller 层

上传文件和下载文件都比较简单,我们就直接在controller层来编写。也不用在pom.xml 中增加什么依赖。所以直接上代码。在controller 包下创建一个file包,在file 包下创建一个FileController 类。

@RestController
@RequestMapping("file")
@Slf4j
public class FileController {@Value("${file.upload.url}")private String uploadFilePath;@RequestMapping("/upload")public String httpUpload(@RequestParam("files") MultipartFile files[]){JSONObject object=new JSONObject();for(int i=0;i<files.length;i++){String fileName = files[i].getOriginalFilename();  // 文件名File dest = new File(uploadFilePath +'/'+ fileName);if (!dest.getParentFile().exists()) {dest.getParentFile().mkdirs();}try {files[i].transferTo(dest);} catch (Exception e) {log.error("{}",e);object.put("success",2);object.put("result","程序错误,请重新上传");return object.toString();}}object.put("success",1);object.put("result","文件上传成功");return object.toString();}}

上面的代码看起来有点多,其实就是一个上传的方法,首先通过 MultipartFile 接收文件。这里我用的是file[] 数组接收文件,这是为了兼容多文件上传的情况,如果只用file 接收,然后在接口上传多个文件的话,只会接收最后一个文件。这里大家注意一下。看自己的需求,我这里兼容多文件所以用数组接收。

然后遍历files 获取文件,下面这段代码是判断文件在所在目录是否存在,如果不存在就创建对应的目录。

 File dest = new File(uploadFilePath +'/'+ fileName);if (!dest.getParentFile().exists()) {dest.getParentFile().mkdirs();}
 files[i].transferTo(dest);

就是将文件存放到对应的服务器,这里有一点需要说明一下,如果我们上传重复的文件会怎么样么?上传重复的文件不会报错,后上传的文件会直接覆盖已经上传的文件。

整体代码就是这样。现在就可以实现文件的上传操作。

测试

我们写好之后,基本上传功能就已经实现了,我们现在来测试一下。启动项目后我们用postman 请求,因为我们需要上传文件,用get 方式请求不了。
在这里插入图片描述

在这里插入图片描述

可以看到文件上传成功了,由此可见,springboot文件上传一个方法就搞定了。

文件下载

其实文件下载,不太建议用接口做,因为文件下载一般都是下载一些静态文件,我们可以先将文件处理好,然后通过Nginx 服务下载静态文件,这样速度会快很多。但是这里我们还是写一下。代码也很简单,就一个方法,也写在fileController 类中

 @RequestMapping("/download")public String fileDownLoad(HttpServletResponse response, @RequestParam("fileName") String fileName){File file = new File(downloadFilePath +'/'+ fileName);if(!file.exists()){return "下载文件不存在";}response.reset();response.setContentType("application/octet-stream");response.setCharacterEncoding("utf-8");response.setContentLength((int) file.length());response.setHeader("Content-Disposition", "attachment;filename=" + fileName );try(BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));) {byte[] buff = new byte[1024];OutputStream os  = response.getOutputStream();int i = 0;while ((i = bis.read(buff)) != -1) {os.write(buff, 0, i);os.flush();}} catch (IOException e) {log.error("{}",e);return "下载失败";}return "下载成功";}

代码也很简单,就是根据文件名判断是否存在文件,不存在就提示没有文件,存在就将文件下载下来。response设置返回文件的格式,以文件流的方式返回,采用utf-8 字符集,设置下载后的文件名。然后就是以文件流的方式下载文件了。

测试的话也简单,我们启动项目,访问接口

 http://localhost:9090/zlflovemm/file/download?fileName=11http://localhost:9090/zlflovemm/file/download?fileName=1.rar

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A8ymBPyk-1639222741198)(https://ask.qcloudimg.com/http-save/yehe-6296056/t0ad4l1ce4.png?imageView2/2/w/1620)]

在这里插入图片描述

可以看到如果文件存在,会直接下载,不会提示下载成功或者失败。

删除文件

删除文件是很简单的,我这里讲一下删除文件下所有文件夹和文件。并做一个定时任务,每天清理一次。

    @Scheduled(cron="0 0 3 * * ?")private void deleteFiles(){deleteFile(new File(deleteFilePath));}public void deleteFile(File file){//判断文件不为null或文件目录存在if (file == null || !file.exists()){log.info("暂无文件");return;}//取得这个目录下的所有子文件对象File[] files = file.listFiles();//遍历该目录下的文件对象for (File f: files){//打印文件名String name = f.getName();log.info(name);//判断子目录是否存在子目录,如果是文件则删除if (f.isDirectory()){deleteFile(f);}else {f.delete();}}//删除空文件夹  for循环已经把上一层节点的目录清空。file.delete();}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/556376.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言的VC开发环境界面介绍,【c语言在vc++6.0中编写界面程序】

到现在为止&#xff0c;C 仍然是计算机编程领域的经典语言之一&#xff0c;C 17 标准在2017上半年已经探讨确定。本期我们汇集了编程专家——祁宇(《深入应用 C 11》作者&#xff0c;C 开源社区 purecpp.org 创始人)的多年心得小结&#xff0c;并具体介绍了 C 17 最新标准中值得…

SpringBoot+VUE 前端加密算法 RSA+DES

前言 为了提高用户登陆的安全性&#xff0c;公司准备整理一份相对安全的登陆模式。 想法 主流加密算法 主流加密算法 &#xff08;一&#xff09;对称加密AES ,其特点是&#xff1a;算法简单&#xff0c;加密速度快&#xff1b; &#xff08;二&#xff09;非对称加密方式&…

spring cloud微服务_年后进大厂,必备这份微服务面试题:Dubbo+SpringBoot+Cloud

Dubbo面试题Dubbo与DubboX区别Dubbo中zookeeper做注册中心&#xff0c;如果注册中心集群都挂掉&#xff0c;发布者和订阅者之间还能通信么&#xff1f;Dubbo中有哪些角色&#xff1f;Dubbo在安全机制方面是如何解决的Dubbo执行流程&#xff1f;Dubbo支持的协议有哪些&#xff1…

全栈工程师薪水_2020 Java 全栈工程师进阶路线图,不可错过

技术更新日新月异&#xff0c;对于初入职场或者刚开始学习的同学来说&#xff0c;经常会困惑该往那个方向发展&#xff0c;这一点所有刚开始学习的人基本都有这个体会的。刚开始学习 Java 那会&#xff0c;最大的问题就是不知道该学什么&#xff0c;以及学习的顺序&#xff0c;…

cookie、Session、Token、sessionStorage、localStorage简介__Token放在 cookie, sessionStorage 和 localStorage中区别

cookie、Session、Token、sessionStorage、localStorage简介 cookie 是一个非常具体的东西&#xff0c;只得是浏览器里永久存储的一种数据&#xff0c;是浏览器实现的一种数据存储功能。Cookie在计算机中是个存储在浏览器目录中的文本文件&#xff0c;当浏览器运行时&#xf…

c语言树莓派音乐播放器,使用web端来控制我的树莓派播放音乐

8种机械键盘轴体对比本人程序员&#xff0c;要买一个写代码的键盘&#xff0c;请问红轴和茶轴怎么选&#xff1f;web端控制树莓派播放音乐&#xff0c;PHPNodeJSmpg123&#xff0c;粗糙版。实现后还可以做个app什么的。代码git用到的代码内容可以在这里看~nodempg.js启动一个se…

Nginx学习_狂神

Nginx 公司产品出现瓶颈&#xff1f; 我们公司项目刚刚上线的时候&#xff0c;并发量小&#xff0c;用户使用的少&#xff0c;所以在低并发的情况下&#xff0c;一个jar包启动应用就够了&#xff0c;然后内部tomcat返回内容给用户。 但是慢慢的&#xff0c;使用我们平台的用户…

js当前时间格式化_JS时间格式化

因为new Date().toLocaleString() 在安卓和ios上的格式不一致&#xff0c;所以尽量自己写format生成一个时间数组作为一个简单的举例&#xff0c;我序列化一周的时间对象声明参数let lastMonth []let daylong 86400000判断时间值是否小于9const formatNumber num > { num…

springboot项目中使用shiro 自定义过滤器和token的方式___shiro使用token登录流程

springboot项目中使用shiro 自定义过滤器和token的方式 实现步骤主要是以下几步&#xff1a; 1. 在项目中导入maven依赖 <dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.4.0</versi…

window.print 点击取消后再次打印无效_教程 | 图书馆自助复印打印机使用方法

图书馆自助复印打印机教程当当当&#xff01;教程君又来辽~今天为大家介绍的是咱们图书馆霸气十足的自助复印打印机实行全程无人化管理为读者提供自助打印、复印、扫描服务是你学习的小帮手&#xff01;实行全程无人化管理为读者提供自助打印、复印、扫描服务读者可在校园内任意…

android 支付模块封装,Android集成支付----支付宝支付总结与封装

前言类似于Android集成支付----微信支付总结与封装(可以查看本人另外一篇文章)&#xff0c;本文对支付宝支付进行一个总结与封装。相比于微信支付&#xff0c;支付宝支付没有那么多坑。集成支付宝支付SDK这里只是简要介绍&#xff0c;重点解说有坑的地方&#xff0c;具体参考官…

Springboot系列之Shiro、JWT、Redis 进行认证鉴权

Springboot系列之Shiro、JWT、Redis 进行认证鉴权 Shiro架构 Apache Shiro是一个轻量级的安全框架 Shiro可以非常容易的开发出足够好的应用&#xff0c;其不仅可以用在JavaSE环境&#xff0c;也可以用在JavaEE环境。 Shiro可以帮助我们完成&#xff1a;认证、授权、加密、会…

kettle 先删除后插入_Kettle:使用触发器和快照表进行增量数据同步

主库为Oracle 11g数据库&#xff0c;针对需要同步的表建立增量数据临时表以及反向并通过水壶定时同步到PostgreSQL数据库。1&#xff0c;主库创建快照表和快照注意&#xff1a;快照表结构和源表结构必须一致&#xff01;--创建插入快照表 CREATE TABLE SPWUSER.WEB_CUSTOMER_IN…

SpringBoot中使用Shiro和JWT做认证和鉴权

最近新做的项目中使用了shiro和jwt来做简单的权限验证&#xff0c;在和springboot集成的过程中碰到了不少坑。做完之后对shiro的体系架构了解的也差不多了&#xff0c;现在把中间需要注意的点放出来&#xff0c;给大家做个参考。 相对于spring security来说&#xff0c;shiro出…

android 手机wifi重启,路由器要不要每天重启?多亏宽带师傅透露,难怪网速一天比一天慢!...

没WiFi&#xff0c;不成活&#xff01;手机和WiFi之间&#xff0c;就像空调加棉被&#xff0c;谁也离不开谁。图片来源于网络如今WiFi已经填满了我们生活的每个角落&#xff0c;很难想象&#xff0c;如果哪天没了网&#xff0c;世界会变成什么样&#xff01;可是家里的WiFi是越…

关于Apache Commons-Lang3的使用

关于Apache Commons-Lang3的使用 在日常工作中&#xff0c;我们经常要使用到一些开源工具包&#xff0c;比如String&#xff0c;Date等等。有时候我们并不清楚有这些工具类的存在&#xff0c;造成在开发过程中重新实现导致时间浪费&#xff0c;且开发的代码质量不佳。而apache…

linux 查看ip_如何在 Linux 中查看可用的网络接口 | Linux 中国

对于某些人来说&#xff0c;他们更偏爱在安装完系统后再进行网络的配置或者更改现存的设置。众所周知&#xff0c;为了在命令行中进行网络设定的配置&#xff0c;我们首先必须知道系统中有多少个可用的网络接口。-- Sk在我们安装完一个 Linux 系统后最为常见的任务便是网络配置…

实现springboot的starter

什么是 Spring Boot Spring Boot 基本上是 Spring 框架的扩展&#xff0c;它消除了设置 Spring 应用程序所需的复杂例行配置。我们在使用 Spring 框架的时候&#xff0c;我们接触得比较多的应该是 Spring MVC、 IOC 、 DI 、AOP 等等&#xff0c;而这些框架在使用的过程中会需…

android多点触摸手势,安卓手势学习笔记(三) 多点触控

8种机械键盘轴体对比本人程序员&#xff0c;要买一个写代码的键盘&#xff0c;请问红轴和茶轴怎么选&#xff1f;跟踪多个触点当多个手指同时触碰屏幕时&#xff0c;系统产生如下的事件&#xff1a;ACTION_DOWN –第一个触点。它启动了手势&#xff0c;在MotionEvent中该触点的…

SpringBoot 自动配置实现流程

&#xff08;1&#xff09;SpringBoot启动的时候加载主配置类&#xff0c;开启了自动配置功能EnableAutoConfiguration。查看SpringBootApplication &#xff08;2&#xff09;查看EnableAutoConfiguration&#xff0c;其作用是利用AutoConfigurationImportSelector给容器中导入…