安装SDK
方式一:在Maven项目中加入依赖项(推荐)
<!-- https://mvnrepository.com/artifact/com.aliyun.oss/aliyun-sdk-oss -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.11.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
如果使用的是java9及以上的版本,则需要添加jaxb的相关依赖项
<!-- https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.activation/activation -->
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<!-- no more than 2.3.3-->
<!-- https://mvnrepository.com/artifact/org.glassfish.jaxb/jaxb-runtime -->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>3.0.0</version>
</dependency>
方式二、在Eclipse项目中导入JAR包
1、下载Java SDK开发包
2、解压该开发包
3、将解压后文件夹中的文件 aliyun-sdk-oss-3.10.2.jar 以及 lib 文件夹下的所有的文件拷贝到您的项目中
4、在Eclipse中选择工程,右键选择Properties > Java Build Path > Add JARs
5、选中拷贝的所有JAR文件,导入到Libraries中
方式三、在IDEA项目中导入JAR包
1、下载Java SDK 开发包
2、解压该开发包
3、将解压后文件夹中的文件 aliyun-sdk-oss-3.10.2jar 以及 lib 文件夹下的所有JAR文件拷贝到您的项目中
4、在IDEA中选择您的工程,右键选择File > Project Structure > Modules > Dependencies > + > JARs or directories
5、选中拷贝所有的JAR文件,导入到Extemal Libraries中
oss-config配置文件
方式一、自定义oss-config.propertes文件
#\u963F\u91CC\u4E91\u8D26\u53F7
access_key_id=**
#\u79D8\u94A5
access_key_secret=**
#endpoint
end_point=http://oss-cn-beijing.aliyuncs.com
#bucket
bucket_name=**
#basePath
base_path=orange-erp
#innerEndPoint
inner_end_point=http://oss-cn-beijing-internal.aliyuncs.com
#publicEndPoint
public_end_point=http://dx-pub-test.oss-cn-beijing.aliyuncs.com
#apkFileUpload
apk_file_upload=http://test.oss.chengzibianli.com
方式二、在yml文件中增加配置文件
# 阿里云oss
oss:
endpoint: http://oss-cn-beijing.aliyuncs.com
accessKeyId: *
accessKeySecret: *
bucketName: *
编写OssConfig.java 文件
1、使用oss-config方式一配置文件:
import com.aliyun.oss.HttpMethod;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
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 java.net.URL;
import java.util.Date;
@Configuration
@PropertySource(value = "classpath:oss-config.properties")
@Getter
@Component
public class OssConfig {
/**
* 阿里云账号id
*/
@Value("${access_key_id}")
private String accessKeyId;
/**
* 阿里云账号密钥
*/
@Value("${access_key_secret}")
private String accessKeySecret;
/**
* 对象存储oss外网endpoint
*/
@Value("${end_point}")
private String endPoint;
/**
* 存储空间
*/
@Value("${bucket_name}")
private String bucketName;
/**
* 存储根目录
*/
@Value("${base_path}")
private String basePath;
/**
* 对象存储oss公共endpoint
*/
@Value("${public_end_point}")
private String publicEndPoint;
/**
* 对象存储oss内网endpoint
*/
@Value("${inner_end_point}")
private String innerEndPoint;
/**
* 阿里云OSS客户端
*/
private OSSClient ossClient;
/**
* 阿里云OSS内网客户端
*/
private OSSClient innerOssClient;
/**
* 阿里云OSS外网客户端
*/
private OSSClient publicOssClient;
public OSSClient getOssClient() {
if (ossClient == null) {
ossClient = new OSSClient(endPoint, new DefaultCredentialProvider(accessKeyId, accessKeySecret), null);
}
return ossClient;
}
public OSSClient getInnerOssClient() {
if (innerOssClient == null) {
innerOssClient = new OSSClient(innerEndPoint, new DefaultCredentialProvider(accessKeyId, accessKeySecret), null);
}
return innerOssClient;
}
public OSSClient getPublicOssClient() {
if (publicOssClient == null) {
publicOssClient = new OSSClient(endPoint, new DefaultCredentialProvider(accessKeyId, accessKeySecret), null);
}
return publicOssClient;
}
public String getPub(String key) {
//设置单个key 为公共读
this.publicOssClient.setObjectAcl(bucketName, StringUtils.removeStart(key, "/"), CannedAccessControlList.PublicRead);
//返回路径
return publicEndPoint + (StringUtils.startsWith(key, "/") ? key : "/" + key);
}
/**
* 生成图片返显url
*
* @param picKey 图片key
* @param expiration 过期时间
* @return url
*/
public String getPicUrl(String picKey, Date expiration) {
GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(bucketName, picKey, HttpMethod.GET);
req.setExpiration(expiration);
URL signedUrl = this.getOssClient().generatePresignedUrl(req);
return signedUrl.toString();
}
2、使用oss-config方式二配置文件:
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "oss")
public class AliyunOssConfig implements InitializingBean {
/**
* 阿里云 oss 站点
*/
private String endpoint;
/**
* 阿里云 oss 公钥
*/
private String accessKeyId;
/**
* 阿里云 oss 私钥
*/
private String accessKeySecret;
/**
* 阿里云 oss 文件根目录
*/
private String bucketName;
//文件最大上传大小
public static long FILE_MAX_SIZE = 1024 * 1024 * 10l;
//图片过期时间 100年
public static long FILE_EXPIRATION_TIME = 1000 * 3600 * 24 * 365 * 100;
public static String JAVA_END_POINT;
public static String JAVA_ACCESS_KEY_ID;
public static String JAVA_ACCESS_KEY_SECRET;
public static String JAVA_BUCKET_NAME;
@Override
public void afterPropertiesSet() throws Exception {
JAVA_END_POINT = endpoint;
JAVA_ACCESS_KEY_ID = accessKeyId;
JAVA_ACCESS_KEY_SECRET = accessKeySecret;
JAVA_BUCKET_NAME = bucketName;
}
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;
}
}
编写oss请求参数和返回结果集
请求参数:
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import lombok.Data;
/** 主要是为了经过编码的文件上传 **/
@Data
@ApiModel
public class FileUploadParam implements Serializable {
@NotNull(message = "文件名称不能为空")
@ApiModelProperty(value = "文件名称")
private String fileName;
@NotNull(message = "文件类型不能为空")
@ApiModelProperty(value = "文件类型")
private String fileType;
/**
* 经过base64编码后的文件
*/
@NotNull(message = "文件内容不能为空")
@ApiModelProperty(value = "文件内容")
private String data;
}
返回结果集:
import lombok.Data;
@Data
public class AliyunOssResult {
/**
* code:200长传成功
* code: 400上传失败
*/
private int code;
/**
* 上传成功的返回url
*/
private String url;
/**
* 错误提示
*/
private String errMsg;
}
上传文件工具类
package com.un.common.utils.oss;
import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.model.*;
import com.un.common.utils.StringUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;
import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
public class AliyunOSSUtil {
/**
* oss 工具客户端
*/
private volatile static OSSClient ossClient = null;
/**
* 上传文件至阿里云 OSS
* 文件上传成功,返回文件完整访问路径
*
* @param file 上传文件
* @return
*/
public static AliyunOssResult upload(MultipartFile file) {
if (file == null) {
return new AliyunOssResult(400, null, "文件不能为空");
}
System.out.println(file.getSize());
if (file.getSize() <= 0 || file.getSize() > AliyunOssConfig.FILE_MAX_SIZE) {
return new AliyunOssResult(400, null, "文件不能大于10M");
}
//文件名称
String oldName = file.getOriginalFilename();
//文件后缀
String postfix = oldName.substring(oldName.lastIndexOf(".") + 1, oldName.length());
//新文件名称
String fileName = UUID.randomUUID().toString().toUpperCase()
.replace("-", "")
+ "." + postfix;
//获取文件类型
String fileType = file.getContentType();
InputStream inputStream = null;
try {
inputStream = file.getInputStream();
} catch (IOException e) {
e.printStackTrace();
return new AliyunOssResult(400, null, e.getMessage());
}
//上传文件
AliyunOssResult resoult = putFile(inputStream, fileType, fileName);
return resoult;
}
/**
* 上传文件
* 主要兼容客户端经过base64位编码的文件
*
* @param param
* @return
*/
public static AliyunOssResult upload(FileUploadParam param) {
if (param == null || StringUtils.isEmpty(param.getData())) {
return new AliyunOssResult(400, null, "文件不能为空");
}
//文件大小判断
if (param.getData().length() <= 0 || param.getData().length() > AliyunOssConfig.FILE_MAX_SIZE) {
return new AliyunOssResult(400, null, "文件不能大于10M");
}
//老文件名
String oldName = param.getFileName();
//文件类型
String fileType = param.getFileType();
//新文件名
String fileName = UUID.randomUUID().toString().toUpperCase()
.replace("-", "")
+ oldName.substring(oldName.lastIndexOf("."), oldName.length());
InputStream inputStream = null;
try {
//将字符串转换为byte数组,这里的content是那一串base64密文
byte[] bytes = new BASE64Decoder().decodeBuffer(param.getData());
inputStream = new ByteArrayInputStream(bytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
return new AliyunOssResult(400, null, e.getMessage());
} catch (IOException e) {
e.printStackTrace();
return new AliyunOssResult(400, null, e.getMessage());
}
//上传文件
AliyunOssResult resoult = putFile(inputStream, fileType, fileName);
return resoult;
}
/**
* 上传文件
*
* @param input
* @param fileType
* @param fileName
* @return
*/
private static AliyunOssResult putFile(InputStream input, String fileType, String fileName) {
AliyunOssResult resoult = null;
//初始化客户端
ossClient = ossClient == null ? initOSS() : ossClient;
try {
// 创建上传Object的Metadata
ObjectMetadata meta = new ObjectMetadata();
// 设置上传内容类型
meta.setContentType(fileType);
//被下载时网页的缓存行为
meta.setCacheControl("no-cache");
//创建上传请求
PutObjectRequest request = new PutObjectRequest(AliyunOssConfig.JAVA_BUCKET_NAME, fileName, input, meta);
//上传文件
ossClient.putObject(request);
//获取上传成功的文件地址
resoult = new AliyunOssResult(200, getOssUrl(ossClient, fileName), null);
System.out.println(resoult);
} catch (OSSException | ClientException e) {
e.printStackTrace();
resoult = new AliyunOssResult(400, null, e.getMessage());
return resoult;
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
return resoult;
}
/**
* 根据文件名生成文件的访问地址
*
* @param ossClient
* @param key
* @return
*/
private static String getOssUrl(OSSClient ossClient, String key) {
Date expiration = new Date(new Date().getTime() + AliyunOssConfig.FILE_EXPIRATION_TIME);// 生成URL
GeneratePresignedUrlRequest generatePresignedUrlRequest;
generatePresignedUrlRequest = new GeneratePresignedUrlRequest(AliyunOssConfig.JAVA_BUCKET_NAME, key);
generatePresignedUrlRequest.setExpiration(expiration);
URL url = ossClient.generatePresignedUrl(generatePresignedUrlRequest);
return url.toString();
}
/**
* 通过文件名下载文件
*
* @param fileNmae 要下载的文件名
* 例如:4DB049D0604047989183CB68D76E969D.jpg
* @param localFileName 本地要创建的文件名
* 例如:C:\Users\Administrator\Desktop\test.jpg
*/
public static void downloadFile(String fileNmae, String localFileName) {
ossClient = ossClient == null ? initOSS() : ossClient;
try {
// 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖,不存在则新建。
ossClient.getObject(new GetObjectRequest(AliyunOssConfig.JAVA_BUCKET_NAME, fileNmae), new File(localFileName));
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
/**
* @param file
* @param fileType
* @param oldUrl
* @return String
* @MethodName: updateFile
* @Description: 更新文件:只更新内容,不更新文件名和文件地址。
* (因为地址没变,可能存在浏览器原数据缓存,不能及时加载新数据,例如图片更新,请注意)
*/
// public static String updateFile(File file, String fileType, String oldUrl) {
// String fileName = getFileName(oldUrl);
// if (fileName == null) return null;
// return putFile(file, fileType, fileName);
// }
/**
* @param file
* @param fileType 文件后缀
* @param oldUrl 需要删除的文件地址
* @return String 文件地址
* @MethodName: replaceFile
* @Description: 替换文件:删除原文件并上传新文件,文件名和地址同时替换
* 解决原数据缓存问题,只要更新了地址,就能重新加载数据)
*/
// public static String replaceFile(File file, String fileType, String oldUrl) {
// boolean flag = deleteFile(oldUrl); //先删除原文件
// if (!flag) {
// //更改文件的过期时间,让他到期自动删除。
// }
// return uploadFile(file, fileType);
// }
/**
* 列举 test 文件下所有的文件
*/
public static List<String> listFile() {
List<String> list = new ArrayList<>();
ossClient = ossClient == null ? initOSS() : ossClient;
try {
// 构造ListObjectsRequest请求。
ListObjectsRequest listObjectsRequest = new ListObjectsRequest(AliyunOssConfig.JAVA_BUCKET_NAME);
// 设置prefix参数来获取fun目录下的所有文件。
// listObjectsRequest.setPrefix("test/");
// 列出文件。
ObjectListing listing = ossClient.listObjects(listObjectsRequest);
// 遍历所有文件。
for (OSSObjectSummary objectSummary : listing.getObjectSummaries()) {
//System.out.println(objectSummary.getKey());
//把key全部转化成可以访问的url
String url = getOssUrl(ossClient, objectSummary.getKey());
list.add(url);
}
// 遍历所有commonPrefix。
// for (String commonPrefix : listing.getCommonPrefixes()) {
// System.out.println(commonPrefix);
// }
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
return list;
}
/**
* @param fileUrls 需要删除的文件url集合
* @return int 成功删除的个数
* @MethodName: batchDeleteFiles
* @Description: 批量文件删除(较慢):适用于不同endPoint和BucketName
*/
private int deleteFiles(List<String> fileUrls) {
int count = 0;
for (String url : fileUrls) {
if (deleteFile(url)) {
count++;
}
}
return count;
}
/**
* @param fileUrls 需要删除的文件url集合
* @return int 成功删除的个数
* @MethodName: batchDeleteFiles
* @Description: 批量文件删除(较快):适用于相同endPoint和BucketName
*/
private int deleteFile(List<String> fileUrls) {
ossClient = ossClient == null ? initOSS() : ossClient;
int deleteCount = 0; //成功删除的个数
try {
//根据url获取fileName
List<String> fileNames = getFileName(fileUrls);
if (AliyunOssConfig.JAVA_BUCKET_NAME == null || fileNames.size() <= 0) return 0;
DeleteObjectsRequest request = new DeleteObjectsRequest(AliyunOssConfig.JAVA_BUCKET_NAME).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 {
if (ossClient != null) {
ossClient.shutdown();
}
}
return deleteCount;
}
/**
* @param fileUrl 需要删除的文件url
* @return boolean 是否删除成功
* @MethodName: deleteFile
* @Description: 单文件删除
* 例如:http://*.oss-cn-beijing.aliyuncs.com/4DB049D0604047989183CB68D76E969D.jpg
*/
public static boolean deleteFile(String fileUrl) {
ossClient = ossClient == null ? initOSS() : ossClient;
try {
//根据url获取fileName
String fileName = getFileName(fileUrl);
if (AliyunOssConfig.JAVA_BUCKET_NAME == null || fileName == null) return false;
GenericRequest request = new DeleteObjectsRequest(AliyunOssConfig.JAVA_BUCKET_NAME).withKey(fileName);
ossClient.deleteObject(request);
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
return true;
}
/**
* @param fileUrl 文件url
* @return String fileName
* @MethodName: getFileName
* @Description: 根据url获取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());
}
/**
* @param fileUrls 文件url
* @return List<String> fileName集合
* @MethodName: getFileName
* @Description: 根据url获取fileNames集合
*/
private List<String> getFileName(List<String> fileUrls) {
List<String> names = new ArrayList<>();
for (String url : fileUrls) {
names.add(getFileName(url));
}
return names;
}
/**
* @param fileType
* @return String
* @MethodName: contentType
* @Description: 获取文件类型
*/
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;
}
/**
* 使用单例模式
* 初始化 oss 客户端
*
* @return
*/
private static OSSClient initOSS() {
if (ossClient == null) {
synchronized (AliyunOSSUtil.class) {
if (ossClient == null) {
ossClient = new OSSClient(AliyunOssConfig.JAVA_END_POINT,
new DefaultCredentialProvider(AliyunOssConfig.JAVA_ACCESS_KEY_ID, AliyunOssConfig.JAVA_ACCESS_KEY_SECRET),
new ClientConfiguration());
}
}
}
return ossClient;
}
}
测试用例
import com.un.common.utils.oss.AliyunOSSUtil;
import com.un.common.utils.oss.AliyunOssResult;
import com.un.common.utils.oss.FileUploadParam;
import com.un.framework.aspectj.lang.annotation.Log;
import com.un.framework.aspectj.lang.enums.BusinessType;
import com.un.framework.web.domain.AjaxResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
@Api("阿里云oss测试")
@RestController
@RequestMapping("/oss")
public class OssTestController {
@Log(title = "上传MultipartFile类型的文件", businessType = BusinessType.UPDATE)
@PostMapping("/uploadFile")
@ApiOperation("上传MultipartFile类型的文件")
public AjaxResult uploadFile(MultipartFile file) throws IOException {
AliyunOssResult result = AliyunOSSUtil.upload(file);
return AjaxResult.success(result);
}
@Log(title = "上传base64编码的文件", businessType = BusinessType.UPDATE)
@PostMapping("/uploadData")
@ApiOperation("上传base64编码的文件")
public AjaxResult uploadData(@RequestBody @Validated FileUploadParam param) throws IOException {
AliyunOssResult result = AliyunOSSUtil.upload(param);
return AjaxResult.success(result);
}
@Log(title = "下载文件", businessType = BusinessType.UPDATE)
@PostMapping("/downloadFile")
@ApiOperation("下载文件")
public AjaxResult downloadFile(String fileNmae, String localFileName) throws IOException {
AliyunOSSUtil.downloadFile(fileNmae, localFileName);
return AjaxResult.success();
}
@Log(title = "删除文件", businessType = BusinessType.UPDATE)
@PostMapping("/deleteFile")
@ApiOperation("删除文件")
public AjaxResult deleteFile(String fileUrl) throws IOException {
AliyunOSSUtil.deleteFile(fileUrl);
return AjaxResult.success();
}
@Log(title = "获取当前系统下所有文件", businessType = BusinessType.UPDATE)
@PostMapping("/listFile")
@ApiOperation("获取当前系统下所有文件")
public AjaxResult listFile() throws IOException {
List<String> list = AliyunOSSUtil.listFile();
return AjaxResult.success(list);
}
}