阿里云 OSS 云存储服务器使用
参考:https://blog.youkuaiyun.com/leipan919134/article/details/101538542
https://blog.youkuaiyun.com/github_36086968/article/details/53113274
阿里云官方java文档
OSS项目集成
项目集成了swagger2自动接口文档,如未集成,需要将@Api、@ApiOperation等注解去掉
前期准备
开通阿里云OSS服务。
https://www.aliyun.com/product/oss?spm=5176.10695662.1112155.2.188e5ad3TaI1Ie&aly_as=cAG1L5Oz
配置文件中的信息需要登录阿里云控制台进行查看以及操作,详见下图。
新建bucket
点击上图的Access key查看密钥
配置文件中的endpiont
代码集成
添加依赖
#pom.xml
<!--阿里云 oss云存储-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.8.0</version>
</dependency>
<!--读取配置文件的时候用到-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
</dependency>
配置文件
#oss.properties
#阿里云OSS配置
oss.endpoint=http://oss-cn-hangzhou.aliyuncs.com
oss.bucketName=qizy-images
#这边access密钥是在阿里云控制台进行查看
oss.accessKeyId=LTAI4FxhWvJEcK9HUh****
oss.accessKeySecret=tCjkdyhbSlPSsZv8dy1******
工具类
# OSSUtil.java
package com.learning.ssm_swagger.util;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.*;
import com.learning.ssm_swagger.entity.ali.STSToken;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.OSSClient;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Component
@Configuration
@PropertySource(value = { "classpath:oss.properties" })
public class OSSUtil {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(OSSUtil.class);
private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
@Value("${oss.accessKeyId}")
public String accessKeyId;
@Value("${oss.accessKeySecret}")
public String accessKeySecret;
@Value("${oss.endpoint}")
public String endpoint;
@Value("${oss.bucketName}")
public String bucketName;
private OSSClient client;
/**************************************************************************
************************ oss对象相关 ****************************
*************************************************************************/
/**
* 初始化oss对象
* @return
*/
private OSSClient initClient() {
if (null == client) {
ClientConfiguration conf = new ClientConfiguration();
conf.setConnectionTimeout(5000);
conf.setMaxErrorRetry(10);
// conf.setProxyHost("127.0.0.1");
// conf.setProxyPort(8080);
client = new OSSClient(endpoint, accessKeyId, accessKeySecret, securityToken, conf);
}
return client;
}
/**
* 获取OSS对象
* @return
*/
public OSSClient getClientObject(){
return initClient();
}
/**************************************************************************
************************ bucket相关 ****************************
*************************************************************************/
/**
* 创建bucket存储空间
* @param bucketName 存储空间名称
* @return Boolean
*/
public Boolean createBucket(String bucketName){
Boolean back = false;
OSSClient ossClient = null;
try {
ossClient = initClient();
//判断bucket是否存在
if(doesBucketExist(bucketName)){
return back;
}
// 创建CreateBucketRequest对象。
CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
// 如果创建存储空间的同时需要指定存储类型以及数据容灾类型, 可以参考以下代码。
// 此处以设置存储空间的存储类型为标准存储为例。
// createBucketRequest.setStorageClass(StorageClass.Standard);
// 默认情况下,数据容灾类型为本地冗余存储,即DataRedundancyType.LRS。如果需要设置数据容灾类型为同城冗余存储,请替换为DataRedundancyType.ZRS。
// createBucketRequest.setDataRedundancyType(DataRedundancyType.ZRS)
// 创建存储空间。
ossClient.createBucket(createBucketRequest);
back = true;
} catch (OSSException oe) {
oe.printStackTrace();
return null;
} catch (ClientException ce) {
ce.printStackTrace();
return null;
} finally {
ossClient.shutdown();
client = null;
}
return back;
}
/**
* 删除指定的bucket
* @param bucketName 存储空间名称
* @return
*/
public Boolean deleteBucket(String bucketName){
Boolean back = false;
OSSClient ossClient = null;
try {
ossClient = initClient();
// 删除存储空间。
ossClient.deleteBucket(bucketName);
back = true;
} catch (OSSException oe) {
oe.printStackTrace();
return null;
} catch (ClientException ce) {
ce.printStackTrace();
return null;
} finally {
ossClient.shutdown();
client = null;
}
return back;
}
/**
* 判断存储空间是否存在
* @param bucketName 存储空间名称
* @return
*/
private Boolean doesBucketExist(String bucketName){
OSSClient ossClient = initClient();
return ossClient.doesBucketExist(bucketName);
}
/**
* 获取所有存储空间
* @return 存储空间集合
*/
public List<Bucket> getAllBuckets(){
OSSClient ossClient = null;
List<Bucket> back = new ArrayList<>();
try {
ossClient = initClient();
back = ossClient.listBuckets();
} catch (OSSException oe) {
oe.printStackTrace();
return null;
} catch (ClientException ce) {
ce.printStackTrace();
return null;
} finally {
ossClient.shutdown();
client = null;
}
return back;
}
/**
* 根据url获取bucketName
* @MethodName: getBucketName
* @Description: 根据url获取bucketName
* @param fileUrl 文件url
* @return String bucketName
*/
public 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);
}
/**************************************************************************
************************ 文件读取相关 **************************
*************************************************************************/
/**
* 上传文件到OSS 成功再返回的文件路径
* @MethodName: putObject
* @Description: 上传文件 底层方法:PutObjectRequest
* @param file
* @param fileType
* @param fileName
* @return String
*/
private String putObject(File file,String fileType,String fileName){
//默认null
String url = null;
OSSClient ossClient = null;
try {
ossClient = initClient();
InputStream input = new FileInputStream(file);
// 创建上传Object的Metadata
ObjectMetadata meta = new ObjectMetadata();
// 设置上传内容类型
meta.setContentType(contentType(fileType));
// 被下载时网页的缓存行为
meta.setCacheControl("no-cache");
//创建上传请求
PutObjectRequest request = new PutObjectRequest(bucketName, fileName,input,meta);
ossClient.putObject(request);
//上传成功再返回的文件路径
url = endpoint.replaceFirst("http://","http://"+bucketName+".")+"/"+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();
client = null;
}
return url;
}
/**
* OSS单文件上传
* @MethodName: uploadFile
* @Description: OSS单文件上传
* @param file
* @param fileType 文件后缀
* @return String 文件地址
*/
public String uploadFile(File file,String fileType){
//文件名,根据UUID来
String fileName = UUID.randomUUID().toString().toUpperCase().replace("-", "")+"."+fileType;
return putObject(file,fileType,fileName);
}
/**
*
* @MethodName: updateFile
* @Description: 更新文件:只更新内容,不更新文件名和文件地址。
* (因为地址没变,可能存在浏览器原数据缓存,不能及时加载新数据,例如图片更新,请注意)
* @param file
* @param fileType
* @param oldUrl
* @return String
*/
public 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 String replaceFile(File file,String fileType,String oldUrl){
//先删除原文件
boolean flag = deleteFile(oldUrl);
if(!flag){
//更改文件的过期时间,让他到期自动删除。
}
return uploadFile(file, fileType);
}
/**
* 根据url,单文件删除
* @MethodName: deleteFile
* @Description: 单文件删除 底层方法:DeleteObjectsRequest
* @param fileUrl 需要删除的文件url
* @return boolean 是否删除成功
*/
public boolean deleteFile(String fileUrl){
//根据url获取bucketName
String bucketName = getBucketName(fileUrl);
//根据url获取fileName
String fileName = getFileName(fileUrl);
if(bucketName==null||fileName==null) {
return false;
}
OSSClient ossClient = null;
try {
ossClient = initClient();
GenericRequest request = new DeleteObjectsRequest(bucketName).withKey(fileName);
ossClient.deleteObject(request);
} catch (Exception oe) {
oe.printStackTrace();
return false;
} finally {
ossClient.shutdown();
client = null;
}
return true;
}
/**
*
* @MethodName: batchDeleteFiles
* @Description: 批量文件删除(较慢):适用于不同endPoint和BucketName
* @param fileUrls 需要删除的文件url集合
* @return int 成功删除的个数
*/
public int deleteFiles(List<String> fileUrls){
int count = 0;
for (String url : fileUrls) {
if(deleteFile(url)){
count++;
}
}
return count;
}
/**
*
* @MethodName: batchDeleteFiles
* @Description: 批量文件删除(较快):适用于相同endPoint和BucketName
* @param fileUrls 需要删除的文件url集合
* @return int 成功删除的个数
*/
public int batchDeleteFiles(List<String> fileUrls){
//成功删除的个数
int deleteCount = 0;
//根据url获取bucketName
String bucketName = getBucketName(fileUrls.get(0));
//根据url获取fileName
List<String> fileNames = getFileName(fileUrls);
if(bucketName==null||fileNames.size()<=0) {
return 0;
}
OSSClient ossClient = null;
try {
ossClient = initClient();
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();
client = null;
}
return deleteCount;
}
/**
* 根据url获取fileName
* @MethodName: getFileName
* @Description: 根据url获取fileName
* @param fileUrl 文件url
* @return String fileName
*/
private String getFileName(String fileUrl){
String str = "aliyuncs.com/";
int beginIndex = fileUrl.indexOf(str);
if(beginIndex==-1) {
return null;
}
return fileUrl.substring(beginIndex+str.length());
}
/**
* 根据url获取fileNames集合
* @MethodName: getFileName
* @Description: 根据url获取fileNames集合
* @param fileUrls 文件url集合
* @return List<String> fileName集合
*/
private List<String> getFileName(List<String> fileUrls){
List<String> names = new ArrayList<>();
for (String url : fileUrls) {
names.add(getFileName(url));
}
return names;
}
/**
* 获取文件类型
* @MethodName: contentType
* @Description: 获取文件类型
* @param fileType 文件类型
* @return String
*/
private 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;
}
/**
* 下载文件至本地
* @param fileUrl 文件oss路径url
* @param filePath 文件本地存储路径
* @return
*/
public boolean downLoadFile(String fileUrl,String filePath){
//根据url获取bucketName
String bucketName = getBucketName(fileUrl);
//根据url获取fileName
String fileName = getFileName(fileUrl);
if(bucketName==null||fileName==null) {
return false;
}
OSSClient ossClient = null;
try {
ossClient = initClient();
ossClient.getObject(new GetObjectRequest(bucketName, fileName), new File(filePath+fileName));
} catch (Exception oe) {
oe.printStackTrace();
return false;
} finally {
ossClient.shutdown();
client = null;
}
return true;
}
/**
* 读取文件内容
* @param fileUrl
* @return
*/
public Boolean readFile(String fileUrl){
//根据url获取bucketName
String bucketName = getBucketName(fileUrl);
//根据url获取fileName
String fileName = getFileName(fileUrl);
if(bucketName==null||fileName==null) {
return null;
}
OSSClient ossClient = null;
try {
ossClient = initClient();
OSSObject ossObject = ossClient.getObject(bucketName, fileName);
// 读取文件内容。
System.out.println("Object content:");
BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent()));
while (true) {
String line = reader.readLine();
if (line == null) {
break;
}
System.out.println("\n" + line);
}
} catch (Exception oe) {
oe.printStackTrace();
return false;
} finally {
ossClient.shutdown();
client = null;
}
return true;
}
}
进行简单的测试
# OSSController.java
package com.learning.ssm_swagger.controller.ali;
import com.learning.ssm_swagger.util.OSSUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.io.*;
/**
* @Author Qizy
* @Date 2019/12/11 9:43
* @Version 1.0
**/
@Controller
@RequestMapping("/oss")
@Api(value="OSS Service Controller", description = "阿里云OSS测试")
public class OSSController {
private final org.slf4j.Logger logger = LoggerFactory.getLogger(getClass());
private static final String TO_PATH="upLoad";
private static final String RETURN_PATH="success";
@Autowired
private OSSUtil ossUtil;
@ApiOperation(value = "OSS云存储-上传图片", notes = "OSS云存储-上传图片", httpMethod = "POST")
@RequestMapping(value = "/testUpload", method = RequestMethod.POST)
@ResponseBody
public String testUpload() throws Exception {
File file = new File("D:\\ocrtest.jpg");
return ossUtil.uploadFile(file, "jpg");
}
@ApiOperation(value = "OSS云存储-删除图片", notes = "OSS云存储-删除图片", httpMethod = "POST")
@RequestMapping(value = "/testDelete", method = RequestMethod.POST)
@ResponseBody
public Boolean testDelete() throws Exception {
return ossUtil.deleteFile("http://qizy-images.oss-cn-hangzhou.aliyuncs.com/CFCD6D66706E494196E5316ADBC63E03.jpg");
}
@ApiOperation(value = "OSS云存储-下载图片", notes = "OSS云存储-下载图片", httpMethod = "POST")
@RequestMapping(value = "/testDownload", method = RequestMethod.POST)
@ResponseBody
public Boolean testDownload() throws Exception {
return ossUtil.downLoadFile("http://qizy-images.oss-cn-hangzhou.aliyuncs.com/ED7EB78834E0408EA0B1DEF79F0C39C1.jpg", "D://");
}
@ApiOperation(value = "OSS云存储-读文件内容", notes = "OSS云存储-读文件内容", httpMethod = "POST")
@RequestMapping(value = "/testRead", method = RequestMethod.POST)
@ResponseBody
public Boolean testRead() throws Exception {
return ossUtil.readFile("http://qizy-images.oss-cn-hangzhou.aliyuncs.com/osstest.txt");
}
}
结果
在阿里云OSS文件控制台中可以看到通过我们代码controller接口进行长传的文件