文章目录
- 1. 概念
- 2. 数据准备
- 3. 实战
- 4. 总结
1. 概念
- 「OSS」的英文全称是Object Storage Service,翻译成中文就是「对象存储服务」,官方一点解释就是对象存储是一种使用HTTP API存储和检索非结构化数据和元数据对象的工具
- 白话文解释就是将系统所要用的文件上传到云硬盘上,该云硬盘提供了文件下载、上传等一列服务,这样的服务以及技术可以统称为OSS,业内提供OSS服务的厂商很多,知名常用且成规模的蓝队云等
- OSS相关的术语
- 存储空间(Bucket): 存储空间是您用于存储对象(Object)的容器,所有的对象都必须隶属于某个存储空间
- 对象/文件(Object): 对象是 OSS 存储数据的基本单元,也被称为OSS的文件。对象由元信息(Object Meta)、用户数据(Data)和文件名(Key)组成。对象由存储空间内部唯一的Key来标识
- 地域(Region): 地域表示 OSS 的数据中心所在物理位置。您可以根据费用、请求来源等综合选择数据存储的地域。详情请查看OSS已经开通的Region
- 访问域名(Endpoint): Endpoint 表示OSS对外服务的访问域名。OSS以HTTP RESTful API的形式对外提供服务,当访问不同地域的时候,需要不同的域名。通过内网和外网访问同一个地域所需要的域名也是不同的。具体的内容请参见各个Region对应的Endpoint,例如杭州 Region 的外网 Endpoint 是 oss-cn-hangzhou.aliyuncs.com,内网 Endpoint 是 oss-cn-hangzhou-internal.aliyuncs.com
- 访问密钥(AccessKey): AccessKey,简称 AK,指的是访问身份验证中用到的AccessKeyId 和AccessKeySecret。OSS通过使用AccessKeyId 和AccessKeySecret对称加密的方法来验证某个请求的发送者身份。AccessKeyId用于标识用户,AccessKeySecret是用户用于加密签名字符串和OSS用来验证签名字符串的密钥,其中AccessKeySecret 必须保密,对于OSS来说,AccessKey的来源有:
- Bucket 的拥有者申请的 AccessKey
- 被 Bucket 的拥有者通过 STS 授权给第三方请求者的 AccessKey
- 被Bucket 的拥有者通过 RAM 授权给第三方请求者的 AccessKey
2. 数据准备
免费的话可以用七牛云,这里我是申请了阿里云的OSS,这里主要是讲一下我们项目需要用的一些oss信息,等下yml配置需要用到
- access-key-id和access-key-secret
- bucket和endpoint
- 上传的文件夹
3. 实战
- 依赖
<!-- mvc的自动配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- oss-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
- yml文件配置
# oss
oss:
access-key-id: xxx
access-key-secret: xxx
bucket: typora-aliyun
endpoint: oss-cn-shanghai.aliyuncs.com
dir: file/
@Component
@ConfigurationProperties(prefix = "oss")
public class OSSProperties{
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucket;
private String dir;
//省略getset
}
- 配置类
@Configuration
public class OSSConfig {
@Autowired
private OSSProperties ossProperties;
@Bean
public OSSClient ossClient(){
OSS ossClient = new OSSClientBuilder().build(ossProperties.getEndpoint(),
ossProperties.getAccessKeyId(),
ossProperties.getAccessKeySecret());
return (OSSClient) ossClient;
}
}
- 工具类
@Component
public class OSSUtil {
@Autowired
private OSSProperties ossProperties;
@Autowired
private OSSClient ossClient;
/**
* 上传图片
*
* @param file
* @param fileName
* @return
* @throws IOException
*/
public String uploadImg2Oss(MultipartFile file, String fileName) throws IOException {
try {
InputStream inputStream = file.getInputStream();
this.uploadFile2OSS(inputStream, fileName);
String url = "https://" + ossProperties.getBucket() + "." + ossProperties.getEndpoint() + "/" + ossProperties.getDir() + fileName;
return url;
} catch (Exception e) {
throw new IOException("图片上传失败");
}
}
/**
* 上传到OSS服务器 如果同名文件会覆盖服务器上的
*
* @param instream 文件流
* @param fileName 文件名称 包括后缀名
* @return 出错返回"" ,唯一MD5数字签名
*/
public String uploadFile2OSS(InputStream instream, String fileName) {
String ret = "";
try {
// 创建上传Object的Metadata
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentLength(instream.available());
objectMetadata.setCacheControl("no-cache");
objectMetadata.setHeader("Pragma", "no-cache");
objectMetadata.setContentType(getcontentType(fileName.substring(fileName.lastIndexOf("."))));
objectMetadata.setContentDisposition("inline;filename=" + fileName);
// 上传文件
PutObjectResult putResult = ossClient.putObject(ossProperties.getBucket(), ossProperties.getDir() + fileName, instream, objectMetadata);
ret = putResult.getETag();
} catch (IOException e) {
System.out.println(e.getMessage());
} finally {
try {
if (instream != null) {
instream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return ret;
}
/**
* Description: 判断OSS服务文件上传时文件的contentType
*/
public static String getcontentType(String filenameExtension) {
if (filenameExtension.equalsIgnoreCase("bmp")) {
return "image/bmp";
}
if (filenameExtension.equalsIgnoreCase("gif")) {
return "image/gif";
}
if (filenameExtension.equalsIgnoreCase("jpeg") || filenameExtension.equalsIgnoreCase("jpg")
|| filenameExtension.equalsIgnoreCase("png")) {
return "image/jpeg";
}
if (filenameExtension.equalsIgnoreCase("html")) {
return "text/html";
}
if (filenameExtension.equalsIgnoreCase("txt")) {
return "text/plain";
}
if (filenameExtension.equalsIgnoreCase("vsd")) {
return "application/vnd.visio";
}
if (filenameExtension.equalsIgnoreCase("pptx") || filenameExtension.equalsIgnoreCase("ppt")) {
return "application/vnd.ms-powerpoint";
}
if (filenameExtension.equalsIgnoreCase("docx") || filenameExtension.equalsIgnoreCase("doc")) {
return "application/msword";
}
if (filenameExtension.equalsIgnoreCase("xml")) {
return "text/xml";
}
return "image/jpeg";
}
}
- controller
@Controller
@RequestMapping("/sysFile")
public class SysFileController {
@Autowired
private ISysFileService fileService;
@Autowired
private OSSUtil ossUtil;
@GetMapping("/toFilePage")
public String toFilePage(){
return "file";
}
@PostMapping("/uploadOss")
@ResponseBody
public AjaxResult uploadOss(@RequestParam(value = "file", required = true) MultipartFile file) throws Exception {
// 原始文件名称,如test.jpg
String fileName = file.getOriginalFilename();
// 唯一的文件名称
String newFileName = getTime()+ "_" + fileName;
// 上传文件,并获取oss上图片的地址,例如:https://typora-aliyun.oss-cn-shanghai.aliyuncs.com/file/20220506202723_test.jpg
String url = ossUtil.uploadImg2Oss(file, newFileName);
//存进数据库
if (url != null) {
SysFile sysFile = new SysFile();
sysFile.setFileName(fileName);
sysFile.setFileUrl(url);
fileService.save(sysFile);
}
return AjaxResult.suc();
}
public String getTime(){
String curTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
return curTime;
}
}
- 页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>
<form enctype="multipart/form-data" method="POST" action="/sysFile/uploadOss">
<input type="file" name="file" />
<input type="submit" value="upload" />
</form>
</body>
</html>
准备完成之后,访问http://localhost:8080/sysFile/toFilePage,上传我们的图片, 可以在阿里oss看到我们上传的图片
4. 总结
上面实战的只是最简单的上传功能,适合小文件上传,oss其实还支持更加复杂的文件操作,比如断点,追加,分片等,需要自己去看一下文档