阿里云OSS存储基于JAVA基本使用(一)

时间:2022-05-08 12:12:24

前段时间公司让研究阿里云OSS,说计划会用起来。OSS就是一个阿里提供的在线存储服务,其实原先公司自己搭建的文件服务器也就能用,不过可能是为了以后的业务扩大着想,让提前研究使用了。OSS的基本概念他官网上有很多资料,我这里也就不再说了。研究了一整子,整理了一些方法,所以这里记录出来。本人是小白一枚,一下的知识竟可能的浅显,但也是我自己研究使用的思路,开始也没有找到一篇全面的使用手册,因为官方的SDK也是简洁的不能再简洁了。

本篇文章希望你先看完官方的API了解一下OSS基本语法和概念再来应该比较容易懂。

1.首先确保你已经注册并开通了OSS服务,并在控制台建立好了bucket,并获取到了accessKeyId和accessKeySecret 2.创建一个配置文件,里面存放OSS需要的endpoit和一些以后可能会改定的配置。 config.properties:

#阿里云OSS配置
endpoint = http://oss-cn-shenzhen.aliyuncs.com //可以选择其他的地址
bucketName = ft-pic //已经在控制台创建的bucket
picLocation = CDoc/cms/ //你上传文件的保存路径,如果bucket中不存在则创建(其实原理并不是文件夹,只是文件名,详情请先阅读官方文档)
accessKeyId = *********** //相应的id和key值,请填写你具体的值,这里不方便展示我自己的。
accessKeySecret = ************


3.创建一个读取配置文件的工具类,这并不是必须的,你可以按照自己的方式来实现配置的调取 SystemConfig.java:
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
* 读取后缀名为“.properties”的文件
* @author
*
*/
public class SystemConfig {

private static final String CONFIG_PROPERTIES="config.properties";

public static String getConfigResource(String key) throws IOException{
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Properties properties = new Properties();
InputStream in = loader.getResourceAsStream(CONFIG_PROPERTIES);
properties.load(in);
String value = properties.getProperty(key);
// 编码转换,从ISO-8859-1转向指定编码
value = new String(value.getBytes("ISO-8859-1"), "UTF-8");
in.close();
return value;
}
}

4.创建一个OSS配置类,用来方便的获取基本信息。
OSSConfig.java:
/**
* @ClassName: OSSConfig
* @Description: OSS配置类
* @author AggerChen
* @date 2016年11月4日 下午3:58:36
*/
class OSSConfig{
private String endpoint; //连接区域地址
private String accessKeyId; //连接keyId
private String accessKeySecret; //连接秘钥
private String bucketName; //需要存储的bucketName
private String picLocation; //图片保存路径

public OSSConfig() {
try {
this.endpoint = SystemConfig.getConfigResource("endpoint");
this.bucketName = SystemConfig.getConfigResource("bucketName");
this.picLocation = SystemConfig.getConfigResource("picLocation");
this.accessKeyId = SystemConfig.getConfigResource("accessKeyId");
this.accessKeySecret = SystemConfig.getConfigResource("accessKeySecret");
} catch (IOException e) {
e.printStackTrace();
}
}

public String getEndpoint() {
return endpoint;
}
public void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}
public String getAccessKeyId() {
return accessKeyId;
}
public void setAccessKeyId(String accessKeyId) {
this.accessKeyId = accessKeyId;
}
public String getAccessKeySecret() {
return accessKeySecret;
}
public void setAccessKeySecret(String accessKeySecret) {
this.accessKeySecret = accessKeySecret;
}
public String getBucketName() {
return bucketName;
}
public void setBucketName(String bucketName) {
this.bucketName = bucketName;
}
public String getPicLocation() {
return picLocation;
}
public void setPicLocation(String picLocation) {
this.picLocation = picLocation;
}
}

5.编写OSS上传工具类
OSSUploadUtil.java:
package com.fortis.cms.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.DeleteObjectsRequest;
import com.aliyun.oss.model.DeleteObjectsResult;
import com.aliyun.oss.model.GenericRequest;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;

/**
*
* @ClassName: OSSUploadUtil
* @Description: 阿里云OSS文件上传工具类
* @author AggerChen
* @date 2016年11月3日 下午12:03:24
*/
public class OSSUploadUtil {

private static OSSConfig config = null;

/**
*
* @MethodName: uploadFile
* @Description: OSS单文件上传
* @param file
* @param fileType 文件后缀
* @return String 文件地址
*/
public static String uploadFile(File file,String fileType){
config = config==null?new OSSConfig():config;
String fileName = config.getPicLocation()+UUID.randomUUID().toString().toUpperCase().replace("-", "")+"."+fileType;//文件名,根据UUID来
return putObject(file,fileType,fileName);
}

/**
*
* @MethodName: updateFile
* @Description: 更新文件:只更新内容,不更新文件名和文件地址。
* (因为地址没变,可能存在浏览器原数据缓存,不能及时加载新数据,例如图片更新,请注意)
* @param file
* @param fileType
* @param oldUrl
* @return String
*/
public static String updateFile(File file,String fileType,String oldUrl){
String fileName = getFileName(oldUrl);
if(fileName==null) return null;
return putObject(file,fileType,fileName);
}

/**
*
* @MethodName: replaceFile
* @Description: 替换文件:删除原文件并上传新文件,文件名和地址同时替换
* 解决原数据缓存问题,只要更新了地址,就能重新加载数据)
* @param file
* @param fileType 文件后缀
* @param oldUrl 需要删除的文件地址
* @return String 文件地址
*/
public static String replaceFile(File file,String fileType,String oldUrl){
boolean flag = deleteFile(oldUrl);//先删除原文件
if(!flag){
//更改文件的过期时间,让他到期自动删除。
}
return uploadFile(file, fileType);
}

/**
*
* @MethodName: deleteFile
* @Description: 单文件删除
* @param fileUrl 需要删除的文件url
* @return boolean 是否删除成功
*/
public static boolean deleteFile(String fileUrl){
config = config==null?new OSSConfig():config;

String bucketName = OSSUploadUtil.getBucketName(fileUrl);//根据url获取bucketName
String fileName = OSSUploadUtil.getFileName(fileUrl);//根据url获取fileName
if(bucketName==null||fileName==null) return false;
OSSClient ossClient = null;
try {
ossClient = new OSSClient(config.getEndpoint(), config.getAccessKeyId(), config.getAccessKeySecret());
GenericRequest request = new DeleteObjectsRequest(bucketName).withKey(fileName);
ossClient.deleteObject(request);
} catch (Exception oe) {
oe.printStackTrace();
return false;
} finally {
ossClient.shutdown();
}
return true;
}

/**
*
* @MethodName: batchDeleteFiles
* @Description: 批量文件删除(较快):适用于相同endPoint和BucketName
* @param fileUrls 需要删除的文件url集合
* @return int 成功删除的个数
*/
public static int deleteFile(List<String> fileUrls){
int deleteCount = 0;//成功删除的个数
String bucketName = OSSUploadUtil.getBucketName(fileUrls.get(0));//根据url获取bucketName
List<String> fileNames = OSSUploadUtil.getFileName(fileUrls);//根据url获取fileName
if(bucketName==null||fileNames.size()<=0) return 0;
OSSClient ossClient = null;
try {
ossClient = new OSSClient(config.getEndpoint(), config.getAccessKeyId(), config.getAccessKeySecret());
DeleteObjectsRequest request = new DeleteObjectsRequest(bucketName).withKeys(fileNames);
DeleteObjectsResult result = ossClient.deleteObjects(request);
deleteCount = result.getDeletedObjects().size();
} catch (OSSException oe) {
oe.printStackTrace();
throw new RuntimeException("OSS服务异常:", oe);
} catch (ClientException ce) {
ce.printStackTrace();
throw new RuntimeException("OSS客户端异常:", ce);
} finally {
ossClient.shutdown();
}
return deleteCount;

}

/**
*
* @MethodName: batchDeleteFiles
* @Description: 批量文件删除(较慢):适用于不同endPoint和BucketName
* @param fileUrls 需要删除的文件url集合
* @return int 成功删除的个数
*/
public static int deleteFiles(List<String> fileUrls){
int count = 0;
for (String url : fileUrls) {
if(deleteFile(url)){
count++;
}
}
return count;
}

/**
*
* @MethodName: putObject
* @Description: 上传文件
* @param file
* @param fileType
* @param fileName
* @return String
*/
private static String putObject(File file,String fileType,String fileName){
config = config==null?new OSSConfig():config;
String url = null;//默认null
OSSClient ossClient = null;
try {
ossClient = new OSSClient(config.getEndpoint(), config.getAccessKeyId(), config.getAccessKeySecret());
InputStream input = new FileInputStream(file);
ObjectMetadata meta = new ObjectMetadata();// 创建上传Object的Metadata
meta.setContentType(OSSUploadUtil.contentType(fileType));// 设置上传内容类型
meta.setCacheControl("no-cache");// 被下载时网页的缓存行为
PutObjectRequest request = new PutObjectRequest(config.getBucketName(), fileName,input,meta);//创建上传请求
ossClient.putObject(request);
url = config.getEndpoint().replaceFirst("http://","http://"+config.getBucketName()+".")+"/"+fileName;//上传成功再返回的文件路径
} catch (OSSException oe) {
oe.printStackTrace();
return null;
} catch (ClientException ce) {
ce.printStackTrace();
return null;
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
} finally {
ossClient.shutdown();
}
return url;
}

/**
*
* @MethodName: contentType
* @Description: 获取文件类型
* @param FileType
* @return String
*/
private static String contentType(String fileType){
fileType = fileType.toLowerCase();
String contentType = "";
switch (fileType) {
case "bmp":contentType = "image/bmp";
break;
case "gif":contentType = "image/gif";
break;
case "png":
case "jpeg":
case "jpg":contentType = "image/jpeg";
break;
case "html":contentType = "text/html";
break;
case "txt":contentType = "text/plain";
break;
case "vsd":contentType = "application/vnd.visio";
break;
case "ppt":
case "pptx":contentType = "application/vnd.ms-powerpoint";
break;
case "doc":
case "docx":contentType = "application/msword";
break;
case "xml":contentType = "text/xml";
break;
case "mp4":contentType = "video/mp4";
break;
default: contentType = "application/octet-stream";
break;
}
return contentType;
}

/**
*
* @MethodName: getBucketName
* @Description: 根据url获取bucketName
* @param fileUrl 文件url
* @return String bucketName
*/
private static String getBucketName(String fileUrl){
String http = "http://";
String https = "https://";
int httpIndex = fileUrl.indexOf(http);
int httpsIndex = fileUrl.indexOf(https);
int startIndex = 0;
if(httpIndex==-1){
if(httpsIndex==-1){
return null;
}else{
startIndex = httpsIndex+https.length();
}
}else{
startIndex = httpIndex+http.length();
}
int endIndex = fileUrl.indexOf(".oss-");
return fileUrl.substring(startIndex, endIndex);
}

/**
*
* @MethodName: getFileName
* @Description: 根据url获取fileName
* @param fileUrl 文件url
* @return String fileName
*/
private static String getFileName(String fileUrl){
String str = "aliyuncs.com/";
int beginIndex = fileUrl.indexOf(str);
if(beginIndex==-1) return null;
return fileUrl.substring(beginIndex+str.length());
}

/**
*
* @MethodName: getFileName
* @Description: 根据url获取fileNames集合
* @param fileUrl 文件url
* @return List<String> fileName集合
*/
private static List<String> getFileName(List<String> fileUrls){
List<String> names = new ArrayList<>();
for (String url : fileUrls) {
names.add(getFileName(url));
}
return names;
}
}


6.调用测试,OSSUploadUtil工具类对外只提供了几个方法:
OSSUploadUtil.uploadFile(File file, String fileType) //单文件上传,type:文件后缀名OSSUploadUtil.updateFile(File file, String fileType, String oldUrl)//更新文件:只更新内容,不更新文件名和文件地址。
OSSUploadUtil.replaceFile(File file, String fileType, String oldUrl)//替换文件,删除源文件并上传新文件,文件名和地址也改变
OSSUploadUtil.deleteFile(List<String> fileUrls) //删除多文件,根据问价url来自定获取其中的bucket和文件名,用于bucket和文件名可能存在不同的,循环调用deleteFile方法
OSSUploadUtil.deleteFile(String fileUrl) //删除单文件
OSSUploadUtil.deleteFiles(List<String> fileUrls) //删除多文件,根据配置直接取删除多个文件,bucket和文件地址从配置中获取,用于多文件bucket和文件名都相同的

总结:
  1. 本例只是简单的运用,当然还有更高级的应用暂时还没有研究,希望以后有空再分享出来。
  2. 其中很多例子,在官方的SDK中都有,本文只是展示了对于我这里适用的方式,其他的多种配置方式请参考官方文档。
  3. 如有问题,可以提出,希望能够交流和共同学习。
  4. 本文示例皆为原创,转载请注明出处。