SpringBoot 整合 apache fileupload 轻松实现文件上传与下载(通用版)

我们以Thymeleaf页面模板引擎为例,简单介绍利用 apache fileupload 工具实现文件上传的功能。

2.1、添加相关依赖包

首先创建一个基础的 Spring Boot 项目,并引入相关的依赖包。

图片

2.2、添加相关配置参数

图片

图片

2.3、文件上传示例

图片

图片

对应文件上传的Controller类,示例如下:

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;@Controller
public class ApacheFileController {/*** 定义文件上传的目录*/private static String FILE_DIR = "/Users/demo/file";/*** 访问 upload3 路径时,跳转到apacheUpload.html页面* @return*/@GetMapping("/upload3")public String index() {return "apacheUpload";}/*** 上传文件,支持多文件/表单上传* @param request* @throws Exception*/@PostMapping("/apacheFileUpload")@ResponseBodypublic String fileUpload(HttpServletRequest request) throws Exception {// 判断上传的文件是普通的表单还是带文件的表单boolean isMultipart = ServletFileUpload.isMultipartContent(request);if(!isMultipart){// 终止方法运行,说明这是一个普通的表单,直接返回return "Upload file fail";}// 1.创建DiskFileItemFactory对象,处理文件上传路径或者大小限制的DiskFileItemFactory factory = getDiskFileItemFactory();// 2.获取ServletFileUploadServletFileUpload upload = getServletFileUpload(factory);// 3.处理上传的文件List<FileItem> fileItems = upload.parseRequest(request);for (FileItem fileItem : fileItems) {// 判断上传的文件是普通的表单还是带文件的表单if (fileItem.isFormField()) {String name = fileItem.getFieldName();String value = fileItem.getString("UTF-8"); // 处理乱码System.out.println(name + ": " + value);} else {// 处理文件String filePath = FILE_DIR + "/" + fileItem.getName();try(InputStream inputStream = fileItem.getInputStream();OutputStream outputStream = new FileOutputStream(filePath)) {// 拷贝文件流IOUtils.copy(inputStream, outputStream);}// 清除临时文件fileItem.delete();System.out.println("上传成功,文件名:" + fileItem.getName());}}return "Upload file success";}/*** 创建DiskFileItemFactory对象* @return*/private DiskFileItemFactory getDiskFileItemFactory() {DiskFileItemFactory factory = new DiskFileItemFactory();// 设置一个缓冲区大小, 当文件大于这个缓冲区大小的时候, 就会放到临时磁盘目录,防止内存崩溃factory.setSizeThreshold(1024 * 1024);// 设置临时磁盘目录, 接收上传的 Filefactory.setRepository(new File(FILE_DIR + "/cache"));return factory;}/*** 获取ServletFileUpload* @param factory* @return*/private ServletFileUpload getServletFileUpload(DiskFileItemFactory factory) {ServletFileUpload upload = new ServletFileUpload(factory);// 监听上传进度upload.setProgressListener(new ProgressListener() {@Overridepublic void update(long pBytesRead, long pContentLength, int pItems) {System.out.println("总大小:" + pContentLength + ",已上传:" + pBytesRead);}});// 处理乱码问题upload.setHeaderEncoding("UTF-8");// 设置单个文件的最大值,-1:表示无限制upload.setFileSizeMax(-1L);return upload;}
}

启动服务后,访问http://localhost:8080/upload3,可以看到如下界面:

图片

图片

图片

在服务控制台,还可以看到上传的进度信息。

图片

2.4、文件下载示例

图片

@Controller
public class DownloadController {private static final String SRC_PATH = "/Users/demo/file";/*** 通过文件名获取文件并以流的形式返回给客户端* @param filename* @param response*/@GetMapping("/download/{filename:.+}")public void download(@PathVariable String filename, HttpServletResponse response) throws Exception {File file = new File(SRC_PATH +'/'+ filename);if(!file.exists()){throw new RuntimeException("下载文件不存在");}response.reset();response.setContentType("application/octet-stream");response.setCharacterEncoding("UTF-8");response.setContentLength((int) file.length());response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));// 使用缓存流,边读边写try(BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) {OutputStream os  = response.getOutputStream();byte[] buff = new byte[1024];int i;while ((i = bis.read(buff)) != -1) {os.write(buff, 0, i);os.flush();}} catch (IOException e) {throw new RuntimeException("下载文件失败");}}
}

图片

最后说一句(求关注!别白嫖!)

如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、在看。

关注公众号:woniuxgg,在公众号中回复:笔记  就可以获得蜗牛为你精心准备的java实战语雀笔记,回复面试、开发手册、有超赞的粉丝福利!

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

QT设计中文输入法软键盘DLL给到C#开发步骤

开发目的&#xff1a;本文提供解决触摸屏C#程序中无法输入中文问题&#xff0c;中文拼音采用开源的谷歌输入法程序、使用QT编译中文输入法界面和中文输入法接口给到C#使用。 开发步骤&#xff1a; 1、QT中设计字母和字符输入界面 2、QT中设计数字输入界面 3、QT中封装调用谷歌…

深度学习:卷积神经网络CNN

目录 一、什么是卷积&#xff1f; 二、卷积神经网络的组成 1. 卷积层 2. 池化层 3. 激活函数 4. 全连接层 三、卷积神经网络的构造 四、代码实现 1.数据预处理 2.创建卷积神经网络 3.创建训练集和测试集函数 4.创建损失函数和优化器并进行训练 一、什么是卷积&…

LPDDR4芯片学习(一)——基础知识与引脚定义

一、基础知识 01 dram基本存储单元 当需要将一位数据存储到DRAM中时&#xff0c;晶体管会充电或放电电容。充电的电容表示逻辑高&#xff08;1&#xff09;&#xff0c;放电的电容表示逻辑低&#xff08;0&#xff09;。由于电容会随着时间泄漏电荷&#xff0c;因此需要定期刷…

学习记录:js算法(四十三):翻转二叉树

文章目录 翻转二叉树我的思路网上思路递归栈 总结 翻转二叉树 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点 图一&#xff1a; 图二&#xff1a; 示例 1&#xff1a;&#xff08;如图一&#xff09; 输入&#xff1a;root [4,2,7,1…

Python记录

1.冒泡排序 时间复杂度O&#xff08;n^2) 选择、插入都是 def bubble(data, reverse):for i in range(len(data)-1):for j in range(len(data)-i-1):if data[j] > data[j1]:data[j], data[j1] data[j1], data[j]if reverse:data.reverse()return data 2.快速排序 时间…

护理陪护小程序|陪护系统||陪护系统开发

在当今社会&#xff0c;随着人口老龄化的加剧和家庭结构的变化&#xff0c;护理与陪护服务的需求日益增长。为了更好地满足这一市场需求&#xff0c;并提升服务效率与质量&#xff0c;护理陪护小程序应运而生。这类小程序不仅为用户提供了便捷、高效的服务预约与管理平台&#…

828华为云征文 | 云服务器Flexus X实例,Docker集成搭建Redis集群

828华为云征文 | 云服务器Flexus X实例&#xff0c;Docker集成搭建Redis集群 Redis 集群是一种分布式的 Redis 解决方案&#xff0c;能够在多个节点之间分片存储数据&#xff0c;实现水平扩展和高可用性。与传统的主从架构不同&#xff0c;Redis 集群支持数据自动分片、主节点故…

J Transl Med结肠癌分子分型+简单实验

目录 技术路线 实验设计&#xff08;药物敏感性&#xff09; 亮点 方法 从 TCGA 和 GEO 数据库下载大量和单细胞 RNA 测序以及 CRC 的临床数据。HRGs 和 LMRGs 来自分子特征数据库。使用 R 软件包 DESeq2 进行差异表达分析。使用无监督聚类进行分子亚型。使用单变量 Cox 回…

嘉宾云集旌城 只为大赛而来 2024ISGC国际烈酒(中国)大奖赛在德阳落下帷幕

秋高气爽、古蜀之源&#xff0c;迎来第六届国际烈酒&#xff08;中国&#xff09;大奖赛&#xff1b;五谷丰登、重装之都&#xff0c;齐聚百名国际烈酒大奖赛评委。 9月18日&#xff0c;由德阳市人民政府、国家葡萄酒及白酒露酒产品质量检验检测中心、上海合作组织多功能经贸平…

图片压缩怎么弄?教你5种图片压缩小技巧

现如今&#xff0c;图片已成为我们日常生活和工作不可或缺的一部分。然而&#xff0c;高清图片往往伴随着庞大的文件体积&#xff0c;给存储和传输带来诸多不便。这时候我们就需要对图片进行适当的压缩处理&#xff0c;那么该怎么做呢&#xff1f;下面教大家5种图片压缩小技巧&…

GBase 8s 安装手册

没有失败&#xff0c;只有暂时停止成功&#xff01; 一&#xff1a;简介 GBase 8s 产品支持多种处理器平台&#xff0c;除国际主流的 x86_64 处理器&#xff08;包括 Intel 和 AMD&#xff09; 外&#xff0c;全面支持飞腾、鲲鹏、龙芯、兆芯、海光、申威等国产处理器。 GBas…

2025秋招内推|招联金融

【投递方式】 直接扫下方二维码&#xff0c;使用内推码: igcefb 【招聘岗位】 深圳&#xff0c;武汉&#xff1a; 后台开发 前端开发 数据开发 数据运营 算法开发 技术运维 软件测试 产品策划 产品运营 客户体验管理 风险管理 资产管理 【校招流程】 简历投递&#xff1a;9月…

kafka 消费者线程安全问题详细探讨

内容概要 主要内容 常见错误案例 下面这段代码大概逻辑 初始化时 实例化KafkaConsumer, 开启线程拉取消息并且处理 资源释放回调 停止线程、调用kafkaConsumer.close进行资源释放 表面上没有问题&#xff0c;但实际上可能出现线程安全问题&#xff0c;因为poll 和 close 两…

Jetpack Compose 核心组件(Text, Images, Buttons)(6)

导读大纲 1.1 基本组件介绍1.2 Text1.2.1 基本用法1.2.2 设计文字风格 1.3 Image组件1.3.1 从各种来源加载图片1.3.2 关键属性1.3.3 如何加载和显示不同类型的图像1.3.4 内容描述和无障碍访问: 1.4 Button组件1.4.1 基本用法1.4.2 装饰和自定义1.4.3 处理按钮点击1.4.4 重要考虑…

基于python深度学习遥感影像地物分类与目标识别、分割实践技术

我国高分辨率对地观测系统重大专项已全面启动&#xff0c;高空间、高光谱、高时间分辨率和宽地面覆盖于一体的全球天空地一体化立体对地观测网逐步形成&#xff0c;将成为保障国家安全的基础性和战略性资源。未来10年全球每天获取的观测数据将超过10PB&#xff0c;遥感大数据时…

JS惰性函数两种实现方式

惰性函数的本质就是函数重写&#xff0c;所谓惰性载入&#xff0c;指函数执行的分支只会发生一次。那什么时函数重写呢&#xff1f;由于一个函数可以返回另一个函数&#xff0c;因此可以用新的函数在覆盖旧的函数。 惰性函数有两种实现方式&#xff1a; 1、在函数被调用时&am…

案例研究丨国控星鲨利用DataEase释放数据潜能,重塑业务视野

国药控股星鲨制药&#xff08;厦门&#xff09;有限公司&#xff08;以下简称为国控星鲨&#xff09;始创于1952年&#xff0c;前身为厦门鱼肝油厂&#xff0c;距今已经有70余年历史&#xff0c;是国家商务部认定的“中华老字号”企业。2011年&#xff0c;国药控股与厦门轻工集…

2024年国庆小长假即将来临,陪猫咪的同时应该如何清浮毛

在父母眼中我们是不是永远都长不大&#xff1f;每次和他们讨论一点事情就开始吵起来。这不&#xff0c;前两天想着和好久不见的朋友去见面&#xff0c;出门前还要被逼问一番。 去到朋友家&#xff0c;发现朋友养了两只可爱的小猫&#xff0c;一时心动上头&#xff0c;我也转身…

通信工程学习:什么是MANO管理编排

MANO&#xff1a;管理编排 MANO&#xff1a;Management and Network Orchestration&#xff08;管理和网络编排&#xff09;在网络功能虚拟化&#xff08;NFV&#xff09;架构中扮演着至关重要的角色。MANO是一个由多个功能实体组合而成的层次&#xff0c;这些功能实体负责管理…

地图定位流程

用户端在小程序认证通过后会自动进行定位&#xff0c;也可以在首页手动定位&#xff0c;定位成功后用户在查询家政服务项目时会根据定位的城市查询该城市有哪些服务项目。 高德地图配置 小程序端的定位是通过手机的定位模块进行定位&#xff0c;定位成功获取经纬度坐标&#x…