黑马JAVAWeb-09 文件上传-文件存储到服务器本地磁盘-文件存储在阿里云
1.文件上传

- 前端 和 服务器端

- 想要上传文件,前端要求


- 代码使用示例(单文件上传接口)
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;@RestController
public class FileUploadController {// 处理单文件上传@PostMapping("/upload")public String uploadFile(@RequestParam("file") MultipartFile file) {// 判断文件是否为空if (file.isEmpty()) {return "请选择要上传的文件";}try {// 获取原始文件名String fileName = file.getOriginalFilename();// 定义文件保存路径(例如:项目根目录下的 upload 文件夹)String filePath = "D:/upload/";File dest = new File(filePath + fileName);// 确保保存目录存在(不存在则创建)if (!dest.getParentFile().exists()) {dest.getParentFile().mkdirs();}// 保存文件到本地file.transferTo(dest);return "文件上传成功,保存路径:" + dest.getAbsolutePath();} catch (IOException e) {e.printStackTrace();return "文件上传失败:" + e.getMessage();}}
}关键说明
接口参数:通过 @RequestParam("file") 绑定前端上传的文件,其中 file 需与前端表单中 input 的 name 属性值一致(如 <input type="file" name="file">)。
- 多文件上传:若需同时上传多个文件,可使用 List 接收
@PostMapping("/upload-multiple")
public String uploadMultipleFiles(@RequestParam("files") List<MultipartFile> files) {// 遍历文件列表,逐个处理for (MultipartFile file : files) {// 处理逻辑同单文件上传...}return "多文件上传完成";
}

2.文件存储到本地
file.transferTo() 就是把用户上传的临时文件 “转移” 并永久保存到你指定的本地位置的关键操作。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;@RestController
public class UploadController {private static final Logger log = LoggerFactory.getLogger(UploadController.class);// 定义文件保存的根目录(实际项目中建议配置在application.properties中,方便修改)private static final String UPLOAD_BASE_DIR = "D:/images/";// 允许上传的文件类型(根据业务需求调整)private static final String[] ALLOWED_CONTENT_TYPES = {"image/jpeg", "image/png", "image/gif", "image/bmp"};// 单个文件最大大小限制(5MB,1MB=1024*1024字节)private static final long MAX_FILE_SIZE = 5 * 1024 * 1024;@PostMapping("/upload")public ResponseEntity<String> upload(@RequestParam String name,@RequestParam Integer age,@RequestParam MultipartFile file) {// 1. 校验文件是否为空if (file.isEmpty()) {return ResponseEntity.badRequest().body("上传失败:请选择文件");}try {// 2. 校验文件大小if (file.getSize() > MAX_FILE_SIZE) {return ResponseEntity.status(HttpStatus.PAYLOAD_TOO_LARGE).body("上传失败:文件大小不能超过5MB");}// 3. 校验文件类型(通过MIME类型判断)String contentType = file.getContentType();boolean isAllowed = false;for (String allowedType : ALLOWED_CONTENT_TYPES) {if (allowedType.equals(contentType)) {isAllowed = true;break;}}if (!isAllowed) {return ResponseEntity.badRequest().body("上传失败:仅支持JPG、PNG、GIF、BMP格式的图片");}// 4. 确保保存目录存在(不存在则创建,包括多级目录)File baseDir = new File(UPLOAD_BASE_DIR);if (!baseDir.exists()) {boolean mkdirsSuccess = baseDir.mkdirs();if (!mkdirsSuccess) {log.error("创建上传目录失败:{}", UPLOAD_BASE_DIR);return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("上传失败:服务器存储目录创建失败");}}// 5. 生成唯一文件名(避免重名覆盖)// 5.1 获取原始文件名的后缀(如.jpg)String originalFilename = file.getOriginalFilename();String fileSuffix = "";if (originalFilename.contains(".")) {fileSuffix = originalFilename.substring(originalFilename.lastIndexOf("."));}// 5.2 生成唯一文件名:UUID + 时间戳 + 后缀(确保唯一性)String uniqueFileName = UUID.randomUUID().toString()+ "_" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())+ fileSuffix;// 6. 构建目标文件路径File destFile = new File(baseDir, uniqueFileName);// 7. 保存文件到本地file.transferTo(destFile);log.info("文件上传成功:{} -> {}", originalFilename, destFile.getAbsolutePath());// 8. 返回成功响应(包含实际保存的文件名)return ResponseEntity.ok("文件上传成功,保存路径:" + destFile.getAbsolutePath());} catch (IOException e) {log.error("文件上传失败", e);return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("上传失败:" + e.getMessage());}}
}

2.文件存储在阿里云OSS
- 存在服务器的本地磁盘,无法无限增大存储容量,磁盘容量终有限
- 生产环境中常采用云服务



- 使用阿里云OSS -少量改动,直接默认选项后确认
- 创建Bucket桶


- 更改权限


- 获取秘钥



