当前位置: 首页 > news >正文

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.mrgr.cn/news/34469.html

相关文章:

  • vue之axios根据某个接口创建实例,并设置headers和超时时间,捕捉异常
  • 代码修改材质参数
  • java:继承题练习
  • 第三十三篇——用变化的眼光看最大值和最小值
  • oneplus3t-lineageos-16.1编译-android9
  • spring中entity的作用
  • 设计模式的六大原则
  • 【HarmonyOS】应用权限原理和封装
  • QT设计中文输入法软键盘DLL给到C#开发步骤
  • 常见框架漏洞
  • JBoss EJBInvokerServlet CVE-2013-4810 反序列化漏洞
  • 线程同步:消费者模型(非常重要的模型)
  • STM32之串口通信
  • 【C++篇】走进C++标准模板库:STL的奥秘与编程效率提升之道
  • Redis:持久化
  • pyqt QGraphicsView 以鼠标为中心进行缩放
  • 2024年9月24日 十二生肖 今日运势
  • 高通Android 12 push framework.jar和service.jar
  • 解决跨域问题的方法
  • WinCC中归档数据片段的时间和尺寸设置
  • 深度学习:卷积神经网络(CNN)基础知识
  • WordPress精选文章如何添加侧边栏和页面?
  • 华为三折叠一拆,苹果脸被打肿了!
  • c++ 类中特殊成员函数
  • 【C++】10道经典面试题带你玩转二叉树
  • 后端开发刷题 | 没有重复项数字的全排列