简介
文件上传(update)是指将本地图片、视频等文件上传到服务器上,可以供其他用户浏览或下载。
前端
文件上传前端三要素:
表单必须有file 域,用于选择要上传的文件。
表单提交方式必须为POST。
表单的编码类型enctype必须要设置为 multipart/form-data。
<!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="name"/><br/>
年龄: <input type="text" name="age"/></br>
图片: <input type="file" name="image"/><br/><br/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
后端
在服务端,我们要想接收上传上来的文件,需要使用Spring给我们提供的一个,专门接收文件的API : MultipartFile。
@RestController
public class UploadController {
@PostMapping("/upload")
public Result upload(MultipartFile image) throws IOException {
System.out.println(image.getName)
return Result.success();
}
}
本地存储
图片上传功能主要分为两步操作:
选择文件,进行图片上传,将图片文件上传到服务器存储起来,然后返回图片访问的URL。
当点击保存时,除了页面的基本表单数据需要提交到服务端,图片访问的URL,也需要提交到服务端。
@RestController
public class UploadController {
@Autowired
private AliOSSUtils aliOSSUtils;
//上传至本地服务器
@PostMapping("/upload")
public Result upload(MultipartFile image) throws IOException {
//获取原始文件名
String originalFilename = image.getOriginalFilename();
//构建新的文件名
String newFileName = UUID.randomUUID().toString()+originalFilename.substring(originalFilename.lastIndexOf("."));
//将文件保存在服务器端 E:/images/ 目录下
image.transferTo(new File("E:/images/"+newFileName));
return Result.success();
}
}
MultipartFile 常见方法:
方法 | 描述 |
getOriginalFilename() | 获取原始文件名 |
getContentType() | 获取文件类型 |
getInputStream() | 获取文件的输入流 |
transferTo(File dest) | 将上传的文件保存到目标文件中 |
getBytes() | 获取文件的字节数组 |
如果是mac系统transferTo方法会报错
此时可以使用获取流的方式,通过流来拷贝。流的操作可以使用commons-io框架,依赖如下:
dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
示例:
RestController
public class FileUploadController {
/**
*
* @param image 接收文件
* @param name 接收前端传过来的name
* @param age 接收前端端传过来的age
* @return
*/
@PostMapping("/upload")
public Result uploadFile(@RequestPart("image") MultipartFile image, String name, Integer age) {
//获取原始名称
String originalFilename = image.getOriginalFilename();
//目标文件
File dest = new File("tlias/serverfile", originalFilename);
try {
//使用commons-io框架进行文件拷贝
FileUtils.copyInputStreamToFile(image.getInputStream(),dest);
return Result.success("提交成功:"+originalFilename + "," + name + "," + age);
} catch (IOException e) {
e.printStackTrace();
return Result.error(e.getMessage());
}
}
}
配置
在进行图片上传的测试中,发现有时候可以上传成功,有时候又不能上传成功,报出如下错误。
报错原因是因为:在SpringBoot中,文件上传,默认单个文件允许最大大小为 1M,如果需要上传大文件,可以在application.properties进行如下配置:
#配置单个文件的最大上传大小
spring.servlet.multipart.max-file-size=10MB
#配置单个请求最大上传大小(一次请求可以上传多个文件)
spring.servlet.multipart.max-request-size=100MB
阿里云OSS
步骤
引入依赖
dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.15.0</version>
</dependency>
引入阿里云OSS文件上传工具类
/**
* 阿里云 OSS 工具类
*/
@Component
public class AliOSSUtils {
private String endpoint = "换成自己bucket的地址";
private String accessKeyId = "替代为自己的accessKeyId";
private String accessKeySecret = "替代为自己的accessKeySecret";
private String bucketName = "替代为自己的bucketName";
/**
* 实现上传图片到OSS
*/
public String upload(MultipartFile multipartFile) throws IOException {
// 获取上传的文件的输入流
InputStream inputStream = multipartFile.getInputStream();
// 避免文件覆盖
String fileName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss")) + multipartFile.getOriginalFilename();
//上传文件到 OSS
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
ossClient.putObject(bucketName, fileName, inputStream);
//文件访问路径
String url = endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + fileName;
// 关闭ossClient
ossClient.shutdown();
return url;// 把上传到oss的路径返回
}
}
案例改造
@RestController
public class UploadController {
@Autowired
private AliOSSUtils aliOSSUtils;
//上传至本地服务器
/*@PostMapping("/upload")
public Result upload(MultipartFile image) throws IOException {
//获取原始文件名
String originalFilename = image.getOriginalFilename();
//构建新的文件名
String newFileName = UUID.randomUUID().toString()+originalFilename.substring(originalFilename.lastIndexOf("."));
//将文件保存在服务器端 E:/images/ 目录下
image.transferTo(new File("E:/images/"+newFileName));
return Result.success();
}*/
@PostMapping("/upload")
public Result upload(MultipartFile image) throws IOException {
String url = aliOSSUtils.upload(image);
return Result.success(url);
}
}