黑马程序员JavaWeb开发教程
文章目录
一、简介
1. 文件上传简介
- 文件上传,是指将本地图片、视频、音频等文件上传到服务器,供其他用户浏览或者下载的过程
- 文件上传在项目中应用非常广泛,我们经常发微博、发微信朋友圈就是用到了文件上传的功能
2. 文件上传前端页面三要素
- 必须有一个表单,表单的提交方式是post
- 表单的编码方式是:multipart/form-data
- 表单中有一个type是:file
3. 代码实现
3.1 前端upload.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上传文件</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
姓名: <input type="text" name="username"><br>
年龄: <input type="text" name="age"><br>
头像: <input type="file" name="image"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
3.2 服务端接收 uploadController
package com.itheima.mytlias.controller;
import com.itheima.mytlias.pojo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@RestController
@Slf4j
public class UploadController {
@PostMapping("/upload")
public Result upload(String username, Integer age, MultipartFile image){
//使用MultipartFile API接受上传的文件,并且表单名称和方法相残名称保持一致,这样就可以接收到(image)
//打印日志
log.info("文件上传:{},{},{}",username,age,image);
//返回结果
return Result.success();
}
}
- 在打印日志的位置打一个断点,之后debug,浏览器访问 http://localhost:8080/upload.html 填入相应的username,age,想上传的文件,点击提交,会跳转到IDEA,可以看到如下的信息:username、age、文件都被接收到了
二、本地存储
1. 本地存储
1.1 基本概念
- 本地存储:在服务端,接收到上传上来的文件之后,将文件存储在本地服务器磁盘当中
1.2 实现
- 只修改 UploadController.java 中的代码即可
package com.itheima.mytlias.controller;
import com.itheima.mytlias.pojo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
@RestController
@Slf4j
public class UploadController {
@PostMapping("/upload")
public Result upload(String username, Integer age, MultipartFile image) throws IOException {
//使用MultipartFile API接受上传的文件,并且表单名称和方法相残名称保持一致,这样就可以接收到(image)
//打印日志
log.info("文件上传:{},{},{}",username,age,image);
//获取原始文件名
String originalFilename = image.getOriginalFilename();
//将文件存储在服务器的磁盘目录中 E:\images
image.transferTo(new File("E:\\image\\"+originalFilename));
//返回结果
return Result.success();
}
}
1.3 测试
- 点击提交之后,去文件夹查看,可以看到文件已经上传过来了
2. 构造唯一的文件名
2.1 构造唯一文件名的原因
- 如果使用原始文件名进行存储,若其中有两个用户上传了具有相同文件名的两个文件,那么就有可能造成其中一个文件被覆盖的问题出现。
2.2 实现方法
- 使用UUID
package com.itheima.mytlias.controller;
import com.itheima.mytlias.pojo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
@RestController
@Slf4j
public class UploadController {
@PostMapping("/upload")
public Result upload(String username, Integer age, MultipartFile image) throws IOException {
//使用MultipartFile API接受上传的文件,并且表单名称和方法相残名称保持一致,这样就可以接收到(image)
//打印日志
log.info("文件上传:{},{},{}", username, age, image);
//获取原始文件名
String originalFilename = image.getOriginalFilename();
//构造唯一文件名(不能重复)- uuid(通用唯一识别码)--ab37845e-02a3-40ae-a7c9-dda1b4f2fe7a
int index = originalFilename.lastIndexOf(".");//找到最后一个.的索引
String extname = originalFilename.substring(index);//截取最后的文件扩展名 例如 .jpg
String newFileName = UUID.randomUUID().toString() + extname;
log.info("新文件名:{}", newFileName);
//将文件存储在服务器的磁盘目录中 E:\images
image.transferTo(new File("E:\\image\\" + newFileName));
//返回结果
return Result.success();
}
}
3. 可能报错
- SizeLimitExceededException
- 解决方法
4. MultipartFile 常用方法
三、阿里云OSS
四、文件上传小结
- 文件上传前端页面三要素(file 表单项、post方式、multipart/form-data)
- 服务端接收文件(MultipartFile)
- 文件存储方式
- 本地存储(无法直接访问、磁盘空间限制、磁盘损坏)
- 云存储OSS