本地存储
简陋的存储方式
public Result upload(String name, Integer age, MultipartFile image) throws Exception{
log.info("文件上传:{},{},{}",username,age,image);
//在控制台显示出相关数据
String originalFilename = image.getOriginalFilename();
image.transferTo(new File("目录"+originalFilename));
return Result.success():
}
该代码中通过上传的方式获取到了一个文件,并将这个文件放在了一个目录之中
目录可以填写想要存储于其中的位置,并将上传的文件以原本的文件名进行重新的一个cv创建
那么此时可以推断出一个问题,就是上传文件名相同的文件会出现后来的文件覆盖前面相同文件名的文件,此时就要引入一个文件命的命名方式:
- uuid:通用唯一识别码,是一个长度固定的字符串,用于构造唯一的文件名
那如何生成一个不会重复的一个字符串呢
String uuid = UUID.randomUUID().toString();
这个不重复的字符串出来之后呢,是没有我们要的文件的后缀名的,只是个文件的名字,没加上文件的类型,所以我们需要手动拼接上
我觉得有两种方式解决拼接
- 是直接自己加上。(虽然感觉不是很规范,但是可以用不同的接口方法,在端口设置方法的时候分开不同类型的,上传不同的东西应该也是不同的功能,所以可以直接加上)
- 是获取出来文件的后缀名。(通过拿到最后一个
.
之后的内容,进行拼接)
String extname = originalFilename.substring(originalFilename.lastIndexOf(","); );
String newFileName = UUID.randomUUID().toString() + extname;
到了这时候大致的代码如下所示
public Result upload(MultipartFile image) throws IOException{
//获取原始文件名
String originalFilename = image.getOriginalFilename();
//构建新的文件名
String newFileName = UUID.randomUUID().toString + originalFilename.substring(originalFilename.lastIndexOf(","));
//将文件保存在服务器端目录下
image.tranferTo(new File("目录"+newFileName));
return Result.success();
}
那么此时又会出现新的问题,就是如果上传的文件太大了,比如说有一张图片有一百个G,那么此时后端就会报错FileSizeLimitExceededException
,对于他的描述则是:The field exceeds its maximum permitted size of 1048576 bytes.
就是说他的默认的文件的大小是限制在一个G的,超过这个大小就会报错。
那该如何解决呢?是时候召唤超级飞侠了!超级飞侠?他们是我的伙伴,每当我遇到困难时他们就会帮我。总部,接通!
在SpringBoot中,文件上传,默认单个文件允许最大大小为1M。如果需要上传大文件,可以进行如下配置:
#配置单个文件最大上传大小
spring.servlet.multipart.max-file-size = 10MB
#配置单个请求最大上传大小(一次请求可以上传多个文件)
spring.servlet.multipart.max-request-size = 100MB
文件上传之本地存储就是将上传上来的文件全部存储在服务器的本地磁盘目录当中
本地存储有很多的缺点
- 前端页面无法直接访问上传的文件
- 磁盘容量问题——磁盘满了
- 磁盘坏了——里面的数据会全部丢失
那么如何解决这个问题呢?总部,接通!
- 搭建文件存储服务。单独用来存储上传的文件。such as:FastDFS、MinIO(需要自己买服务器,自己搭建)
- 使用现成的别的公司提供好的云服务。such as:阿里云、腾讯云、华为云and so on
第三方服务
阿里云OSS
what is 云?
就是云端,就是互联网(向云端~)
云服务就是通过互联网对外提供的各种各样的服务
阿里云对象存储OSS(Object Storage Service),是一款海量、安全、低成本、高可靠的云存储服务。
使用OSS,就可以通过网络随时存储和调用包括文本、图片、音频和视频在内的各种文件。
通用思路
准备工作——>参照官方SDK编写入门程序——>集成使用
- 准备工作
- 账号注册
- 实名认证
- 充值
- 开通对象存储服务(OSS)
- 创建bucket
- 获取AccessKey密钥
Bucket:存储空间是用户用于存储对象(Object,就是文件)的容器,所有的对象都必须隶属于某个存储空间。
- 参照官方SDK编写入门程序
SDK:Software Development Kit的缩写,软件开发工具包,包括辅助软件开发的依赖(jar包)、代码示例等,都可以叫做SDK
- 集成使用
使用配置&简陋的使用
- 首先就是依赖添加
可以看阿里云官方文档当中的使用说明
里面不仅有使用配置,还有上传文件,下载文件,管理文件and so on
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.15.1</version>
</dependency>
如果是java9以上的版本,则还需要添加
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<!-- no more than 2.3.3-->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.3</version>
</dependency>
- 代码编写
在阿里云的帮助文档中,会给出详细的代码使用,只要cv并且改变自己的信息内容即可使用
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import java.io.File;
public class Demo {
public static void main(String[] args) throws Exception {
// Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// 填写Bucket名称,例如examplebucket。
String bucketName = "examplebucket";
// 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
String objectName = "exampledir/exampleobject.txt";
// 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。
// 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件。
String filePath= "D:\\localpath\\examplefile.txt";
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
try {
// 创建PutObjectRequest对象。
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new File(filePath));
// 如果需要上传时设置存储类型和访问权限,请参考以下示例代码。
// ObjectMetadata metadata = new ObjectMetadata();
// metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
// metadata.setObjectAcl(CannedAccessControlList.Private);
// putObjectRequest.setMetadata(metadata);
// 上传文件。
PutObjectResult result = ossClient.putObject(putObjectRequest);
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
正式开发
- 引入阿里云OSS上传文件工具类(由官方的示例代码改造而来)
- 上传图片接口开发