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

Spring开发系统时如何实现上传和下载文件

代码如下

值得注意的是上传时候不需要参数servletRequest而下载时候却需要servletResponse,这是为什么呢?

这是因为文件上传时,客户端通过 HTTP POST 请求将文件数据放在 请求体(Body) 中。Spring MVC 对上传过程进行了高度封装,开发者无需直接操作 HttpServletRequest:

  • 框架自动解析:当请求的 Content-Type 为 multipart/form-data 时,Spring 会自动解析请求体,并将文件内容封装为 MultipartFile 对象。

  • 简化参数绑定:通过 @RequestParam(“file”) MultipartFile file 即可直接获取文件对象,无需手动从 HttpServletRequest 中提取数据。

那为什么需要servletResponse呢?

  • 因为文件内容需要直接写入响应输出流,而 Spring 的 @ResponseBody 或 ResponseEntity 适用于结构化数据(如 JSON),不适合大文件流式传输。
package com.xxx.xxxxx.controller;import com.xxx.xxxxx.common.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.UUID;/*** 文件上传和下载*/
@RestController
@RequestMapping("/common")
@Slf4j
public class CommonController {// 这个在application.yml里配置@Value("${reggie.path}")private String basePath;/*** 文件上传* @param file* @return*/@PostMapping("/upload")public httpResp<String> upload(@RequestParam("file") MultipartFile file){// file是一个临时文件,需要转存到指定位置,否则本次请求完成后临时文件会删除log.info(file.toString());//原始文件名String originalFilename = file.getOriginalFilename();//abc.jpgString suffix = originalFilename.substring(originalFilename.lastIndexOf("."));//使用UUID重新生成文件名,防止文件名称重复造成文件覆盖String fileName = UUID.randomUUID().toString() + suffix;//dfsdfdfd.jpg//创建一个目录对象File dir = new File(basePath);//判断当前目录是否存在if(!dir.exists()){//目录不存在,需要创建dir.mkdirs();}try {// 将临时文件转存到指定位置file.transferTo(new File(basePath + fileName));} catch (IOException e) {e.printStackTrace();}return httpResp.success(fileName);}/*** 文件下载* @param name* @param response*/@GetMapping("/download")public void download(String name, HttpServletResponse response){try {//输入流,通过输入流读取文件内容FileInputStream fileInputStream = new FileInputStream(new File(basePath + name));//输出流,通过输出流将文件写回浏览器,因为我们要把文件返还回去,所以要ServletResponseServletOutputStream outputStream = response.getOutputStream();response.setContentType("image/jpeg");int len = 0;byte[] bytes = new byte[1024];while ((len = fileInputStream.read(bytes)) != -1){outputStream.write(bytes,0,len);outputStream.flush();}//关闭资源outputStream.close();fileInputStream.close();} catch (Exception e) {e.printStackTrace();}}
}
http://www.xdnf.cn/news/8057.html

相关文章:

  • Java转Go日记(五十四):gin路由
  • P1833 樱花
  • 端口号详解(技术向)
  • Java之函数式接口、lambda表达式、stream流操作、Optional容器、方法引用
  • 企业级调度器LVS
  • Java读写分离实战
  • Java SpringBoot 项目中 Redis 存储 Session 具体实现步骤
  • Java阻塞队列(BlockingQueue)的使用:ArrayBlockingQueue类、LinkedBlockingQueue类
  • JVM参数详解与实战案例指南(AI)
  • BurpSuite学习安装
  • MobaXterm 解除只能保存14个session会话限制
  • 篇章十 消息持久化(二)
  • 加密软件对企业安全的帮助
  • 水浒后传-暹罗国建立新国家的故事
  • 影刀Fun叉鸟-2048
  • 【强化学习】PPO如何根据奖励模型调整模型参数
  • 使用 OpenCV 实现哈哈镜效果
  • Python-阶跃函数与激活函数
  • 项目中常用的docker指令
  • 免下载苹果IPA文件重签名工具:快速更换应用名称和BID(Bundle Identifier)的详细教程
  • 【GESP真题解析】第 20 集 GESP 一级 2025 年 3 月编程题 1:图书馆的老鼠
  • 提升搜索效率:深入了解Amazon Kendra的强大功能
  • 内核调试高手养成实战 · Day 2:i.MX8MP 实战调试 Vivante GPU 驱动
  • Spring AI 1.0 GA 正式发布
  • 信号量机制:操作系统中的同步与互斥利器
  • openlayer:11点击地图上省份实现overlay提示省份名称并修改对应所点省份区域颜色
  • c++11的auto关键一篇文章打通:基本用法、常见使用场景、最佳食用指南
  • 小刚说C语言刷题—1153 - 查找“支撑数”
  • Docker面试题(1)
  • MinIO纠删码技术解析:数据冗余与高可用的存储密码