
- 一、对象存储 OSS
- 二、使用方式
- 三、开始使用
- 1、maven依赖
- 2、配置类:AliyunOssConfig
- 3、yml配置
- 4、工具类 AliyunOSSUtil
- 5、OssController
对象存储服务(Object Storage Service,OSS)是一种海量、安全、低成本、高可靠的云存储服务,适合存放任意类型的文件。容量和处理能力d性扩展,多种存储类型供选择,全面优化存储成本。
官方学习:https://help.aliyun.com/product/31815.html
二、使用方式-
服务端上传
这个就是文件经过后台上传,需要注意的是,在使用MultipartFile类时,最大默认1M。需要修改上传文件的大小限制。大文件不推荐这种方式上传。 -
服务端签名直传
意思就是后端生成签名,返回到前端,前端通过签名直接上传到aliyun的oss上,这样可以保证秘钥不可见,提高上传 *** 作的安全性与效率。
可参考:https://help.aliyun.com/document_detail/31926.html
这里后端可以设置对应的callback,当成功上传到oss后,oss将上传文件的信息回调给服务端,服务端可以根据回调的url去做后续处理。
首先安装aliyun oss的SDK。
https://help.aliyun.com/document_detail/32009.html
下面使用的maven依赖:
2、配置类:AliyunOssConfigcom.aliyun.oss aliyun-sdk-oss3.10.2
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
@Data
@Slf4j
@Configuration
@ConfigurationProperties(prefix = "aliyun.oss")
public class AliyunOssConfig {
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
private String filePath;
@PostConstruct
public void init(){
log.debug("oss: endpoint:{},accessKeyId:{},bucketName:{},filePath:{}", endpoint, accessKeyId, bucketName, filePath);
}
}
3、yml配置
这里注意下,如果是后端上传文件,需要配置spring.servlet.multipart,
否则在使用MultipartFile类时,最大默认1M。
aliyun:
oss:
accessKeyId: L*****************
accessKeySecret: s**************
bucketName: bucketName
endpoint: oss-cn-hangzhou.aliyuncs.com
filePath: filePath
spring:
servlet:
multipart:
max-file-size: 500MB
max-request-size: 500MB
4、工具类 AliyunOSSUtil
package com.tmzh.saas.sfds.oss.utils;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;
@Slf4j
@Component
public class AliyunOSSUtil {
private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
private static final long EXPIRTATION_TIME = 60*1000;
private static final long CONTENT_LENGTH_RANGE_MIN = 0;
private static final long CONTENT_LENGTH_RANGE_MAX = 1024*1024*1000;
@Autowired
private AliyunOssConfig aliyunOssConfig;
private OSS getOssClient() {
return new OSSClientBuilder().build(aliyunOssConfig.getEndpoint(), aliyunOssConfig.getAccessKeyId(), aliyunOssConfig.getAccessKeySecret());
}
public boolean isExistFile(String fileName) {
OSSClient ossClient = (OSSClient) getOssClient();
boolean isExist;
try {
isExist = ossClient.doesObjectExist(aliyunOssConfig.getBucketName(), fileName);
log.info("oss判断文件:{} 是否存在:{}", fileName,isExist);
} catch (Exception e) {
log.error("oss判断文件存在性异常", e);
} finally {
ossClient.shutdown();
}
return isExist;
}
public String upload(MultipartFile file) {
OSSClient ossClient = (OSSClient) getOssClient();
String fileName = file.getOriginalFilename();
log.info("=========>OSS文件上传开始:" + fileName);
String datePath = format.format(new Date());
try {
//容器不存在,就创建
if (!ossClient.doesBucketExist(aliyunOssConfig.getBucketName())) {
ossClient.createBucket(aliyunOssConfig.getBucketName());
CreateBucketRequest createBucketRequest = new CreateBucketRequest(aliyunOssConfig.getBucketName());
createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
ossClient.createBucket(createBucketRequest);
}
// 获取上传的文件的输入流
InputStream inputStream = file.getInputStream();
//在文件名称里面添加随机唯一值,使用UUID生成
// String uuid = UUID.randomUUID().toString().replaceAll("-", "");
fileName = aliyunOssConfig.getFilePath() + "/" + datePath + "/" + fileName;
// 如果需要上传时设置存储类型与访问权限
PutObjectRequest putObjectRequest = new PutObjectRequest(aliyunOssConfig.getBucketName(), fileName, inputStream);
Objectmetadata metadata = new Objectmetadata();
metadata.setContentType(RequestUtil.getContentType(fileName.substring(fileName.lastIndexOf("."))));
putObjectRequest.setmetadata(metadata);
PutObjectResult result = ossClient.putObject(putObjectRequest);
//设置权限 这里是公开读
ossClient.setBucketAcl(aliyunOssConfig.getBucketName(), CannedAccessControlList.PublicRead);
if (null != result) {
String url = "https://" + aliyunOssConfig.getBucketName() + "." + aliyunOssConfig.getEndpoint() + "/" + fileName;
log.info("==========>OSS文件上传成功,OSS地址:" + url);
return url;
}
} catch (Exception e) {
log.error("oss上传异常", e);
} finally {
//关闭
ossClient.shutdown();
}
return null;
}
public boolean deleteFile(String fileName) {
OSSClient ossClient = (OSSClient) getOssClient();
log.info("=========>OSS文件删除开始");
try {
if (!ossClient.doesBucketExist(aliyunOssConfig.getBucketName())) {
log.error("Bucket不存在");
}
ossClient.deleteObject(aliyunOssConfig.getBucketName(), fileName);
log.info("==============>Object删除成功:" + fileName);
return true;
} catch (Exception e) {
log.error("oss删除异常", e);
} finally {
//关闭
ossClient.shutdown();
}
}
public List getObjectList(String filePath) {
OSSClient ossClient = (OSSClient) getOssClient();
String datePath = format.format(new Date());
List listRe = new ArrayList<>();
try {
log.info("===========>查询文件名列表");
ListObjectsRequest listObjectsRequest = new ListObjectsRequest(aliyunOssConfig.getBucketName());
// listObjectsRequest.setPrefix(aliyunOssConfig.getFilePath() + "/" + datePath + "/");
listObjectsRequest.setPrefix(filePath);
ObjectListing list = ossClient.listObjects(listObjectsRequest);
// OSSobjectSummary下包含目录下所有的文件,不包含子目录
for (OSSObjectSummary objectSummary : list.getObjectSummaries()) {
listRe.add(objectSummary.getKey());
}
return listRe;
} catch (Exception ex) {
log.error("==========>查询列表失败", ex);
return new ArrayList<>();
}
}
public Map getUploadToken(String fileName) {
OSSClient ossClient = (OSSClient) getOssClient();
String datePath = format.format(new Date());
try{
log.info("===========>获取uploadToken");
String dir = aliyunOssConfig.getFilePath()+ "/" + datePath +"/";
long currentTime = System.currentTimeMillis();
String key = dir + fileName.split("\.")[0] + "-" + currentTime + "." + fileName.split("\.")[1];
long expireEndTime = currentTime + EXPIRTATION_TIME;
Date expiration = new Date(expireEndTime);
PolicyConditions policyConds = new PolicyConditions();
policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, CONTENT_LENGTH_RANGE_MIN, CONTENT_LENGTH_RANGE_MAX);
policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
byte[] binaryData = postPolicy.getBytes(StandardCharsets.UTF_8);
String encodedPolicy = BinaryUtil.tobase64String(binaryData);
String postSignature = ossClient.calculatePostSignature(postPolicy);
//JSonObject jasonCallback = new JSonObject();
//你的回调URL
//jasonCallback.put("callbackUrl", String.format("%s/callback/imgUploadSuccess", apiDomain));
//阿里云回调返回参数
//jasonCallback.put("callbackBody", "id=" + id + "&filename=${object}&type=" + type + "&etag=${etag}&size=${size}&height=${imageInfo.height}&width=${imageInfo.width}&mimeType=${mimeType}");
//asonCallback.put("callbackBodyType", "application/x-www-form-urlencoded");
//String base64CallbackBody = BinaryUtil.tobase64String(jasonCallback.toString().getBytes());
Map res = new HashMap<>();
//res.put("callback", base64CallbackBody);
res.put("key", key); //dir + fileName (上传Object的名称。)
res.put("OSSAccessKeyId", aliyunOssConfig.getAccessKeyId());
res.put("policy", encodedPolicy); //Policy规定了请求表单域的合法性。
res.put("signature", postSignature); //根据AccessKey Secret和Policy计算的签名信息,OSS验证该签名信息从而验证该Post请求的合法性。
res.put("dir", dir); //前缀
res.put("uploadUrl", "https://" + aliyunOssConfig.getBucketName() + "." + aliyunOssConfig.getEndpoint()); // "https://" + bucketname + '.' + endpoint; (前端请求oss服务路径)
res.put("expire", String.valueOf(expireEndTime / 1000));
res.put("success_action_status", "200");
log.debug("res:{}",res);
return res;
}
catch (Exception e){
log.error("==========>获取uploadToken失败", e);
}
finally {
ossClient.shutdown();
}
return null;
}
}
5、OssController
@RestController
@Api(tags = "OSS模块")
@RequestMapping("/oss/file")
public class OssController extends baseController{
@Autowired
private AliyunOSSUtil aliyunOSSUtil;
@PostMapping("/upload")
@ApiOperation(value = "上传")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "form", dataType = "MultipartFile", dataTypeClass = MultipartFile.class, name = "file",
value = "文件", required = true)})
public ResponseEntity upload(@RequestParam("file") MultipartFile multipartFile) {
return ok(aliyunOSSUtil.upload(multipartFile));
}
@GetMapping("/list")
@ApiOperation(value = "文件列表")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "query", dataType = "String", dataTypeClass = String.class, name = "filePath",
value = "bucket下的文件路径,例如: filePath/", required = true)})
public ResponseEntity list(@RequestParam("filePath") String filePath) {
return ok(aliyunOSSUtil.getObjectList(filePath));
}
@GetMapping("/isExist")
@ApiOperation(value = "判断文件是否存在")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "query", dataType = "String", dataTypeClass = String.class, name = "fileName",
value = "例如:filePath/fileName", required = true)})
public ResponseEntity isExist(@RequestParam("fileName") String fileName) {
return ok(aliyunOSSUtil.isExistFile(fileName));
}
@DeleteMapping("/delete")
@ApiOperation(value = "删除文件")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "query", dataType = "String", dataTypeClass = String.class, name = "fileName",
value = "例如:filePath/fileName", required = true)})
public ResponseEntity delete(@RequestParam("fileName") String fileName) {
return ok(aliyunOSSUtil.deleteFile(fileName));
}
@PostMapping("/uploadToken")
@ApiOperation(value = "获取uploadToken")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "form", dataType = "String", dataTypeClass = String.class, name = "fileName",
value = "文件名", required = true)})
public ResponseEntity uploadToken(@RequestParam("fileName") String fileName) {
return ok(aliyunOSSUtil.getUploadToken(fileName));
}
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)