博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
阿里云OSS工具类
阅读量:6416 次
发布时间:2019-06-23

本文共 6286 字,大约阅读时间需要 20 分钟。

【前言】

       我们上家公司的存储系统用的是FastDFS();现在在职的公司用的是阿里云的OSS(),在工作的时候整理一个上传OSS文件的工具类,现在与大家分享一下。

【工具类】

       1、工具类的代码:

 
package zhanghan.oss.utils;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import com.fasterxml.jackson.annotation.JsonValue;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import zhanghan.oss.exception.OSSCreateBucketRuntimeException;
import zhanghan.oss.exception.OSSGeneratePresignedUrlRuntimeException;
import zhanghan.oss.exception.OssPutObjectRuntimeException;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import java.util.UUID;
/**
* OSS上传工具类-张晗-2017/10/10
*/
public class OSSUtil {
private volatile static OSSClient instance;
private OSSUtil() {
}
/**
* 单例
* @return OSS工具类实例
*/
private static OSSClient getOSSClient() {
if (instance == null) {
synchronized (OSSUtil.class) {
if (instance == null) {
instance = new OSSClient(OSS_END_POINT, OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET);
}
}
}
return instance;
}
//定义日志
private final static LogUtils logger = LogUtils.getLogger(OSSUtil.class);
//OSS 的地址
private final static String OSS_END_POINT = "http://oss-cn-qingdao.aliyuncs.com";
//OSS 的key值
private final static String OSS_ACCESS_KEY_ID = "OSSKEY";
//OSS 的secret值
private final static String OSS_ACCESS_KEY_SECRET = "OSSSECRET";
//OSS 的bucket名字
private final static String OSS_BUCKET_NAME = "zhanghan-test";
//设置URL过期时间为10年
private final static Date OSS_URL_EXPIRATION = DateUtils.addDays(new Date(), 365 * 10);
//文件路径的枚举
public enum FileDirType {
ZHANGHAN_TEST("test");
private String dir;
FileDirType(String dir) {
this.dir = dir;
}
@JsonValue
public String getDir() {
return dir;
}
}
/**
* 上传文件---去除URL中的?后的时间戳
* @param file 文件
* @param fileDir 上传到OSS上文件的路径
* @return 文件的访问地址
*/
public static String upload(MultipartFile file, FileDirType fileDir) {
OSSUtil.createBucket();
String fileName = OSSUtil.uploadFile(file, fileDir);
String fileOssURL = OSSUtil.getImgUrl(fileName, fileDir);
int firstChar = fileOssURL.indexOf("?");
if (firstChar > 0) {
fileOssURL = fileOssURL.substring(0, firstChar);
}
return fileOssURL;
}
/**
* 当Bucket不存在时创建Bucket
*
* @throws OSSException 异常
* @throws ClientException Bucket命名规则:
* 1.只能包含小写字母、数字和短横线,
* 2.必须以小写字母和数字开头和结尾
* 3.长度在3-63之间
*/
private static void createBucket() {
try {
if (!OSSUtil.getOSSClient().doesBucketExist(OSS_BUCKET_NAME)) {
//判断是否存在该Bucket,不存在时再重新创建
OSSUtil.getOSSClient().createBucket(OSS_BUCKET_NAME);
}
} catch (Exception e) {
logger.error("{}", "创建Bucket失败,请核对Bucket名称(规则:只能包含小写字母、数字和短横线,必须以小写字母和数字开头和结尾,长度在3-63之间)");
throw new OSSCreateBucketRuntimeException("创建Bucket失败,请核对Bucket名称(规则:只能包含小写字母、数字和短横线,必须以小写字母和数字开头和结尾,长度在3-63之间)");
}
}
/**
* 上传到OSS服务器 如果同名文件会覆盖服务器上的
* @param file 文件
* @param fileDir 上传到OSS上文件的路径
* @return 文件的访问地址
*/
private static String uploadFile(MultipartFile file, FileDirType fileDir) {
String fileName = String.format(
"%s.%s",
UUID.randomUUID().toString(),
FilenameUtils.getExtension(file.getOriginalFilename()));
try (InputStream inputStream = file.getInputStream()) {
//创建上传Object的Metadata
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentLength(inputStream.available());
objectMetadata.setCacheControl("no-cache");
objectMetadata.setHeader("Pragma", "no-cache");
objectMetadata.setContentType(getContentType(FilenameUtils.getExtension("." + file.getOriginalFilename())));
objectMetadata.setContentDisposition("inline;filename=" + fileName);
//上传文件
PutObjectResult putResult = OSSUtil.getOSSClient().putObject(OSS_BUCKET_NAME, fileDir.getDir() + fileName, inputStream, objectMetadata);
return fileName;
} catch (Exception e) {
logger.error("{}", "上传文件失败");
throw new OssPutObjectRuntimeException("上传文件失败");
}
}
/**
* 获得文件路径
* @param fileUrl 文件的URL
* @param fileDir 文件在OSS上的路径
* @return 文件的路径
*/
private static String getImgUrl(String fileUrl, FileDirType fileDir) {
if (StringUtils.isEmpty(fileUrl)) {
logger.error("{}", "文件地址为空");
throw new RuntimeException("文件地址为空");
}
String[] split = fileUrl.split("/");
//获取oss图片URL失败
URL url = OSSUtil.getOSSClient().generatePresignedUrl(OSS_BUCKET_NAME, fileDir.getDir() + split[split.length - 1], OSS_URL_EXPIRATION);
if (url == null) {
logger.error("{}", "获取oss文件URL失败");
throw new OSSGeneratePresignedUrlRuntimeException("获取oss文件URL失败");
}
return url.toString();
}
/**
* 判断OSS服务文件上传时文件的contentType
*
* @param FilenameExtension 文件后缀
* @return 后缀
*/
private 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";
}
}

       2、调用工具类的代码:

 
/**
* 上传文件测试
* @param multipartFile 待上传的文件
* @return 上传在OSS文件的访问路径
* @throws BusinessException 上传异常
*/
public String uploadTest(MultipartFile multipartFile) throws BusinessException{
try {
uploadResult = OSSUtil.upload(multipartFile, OSSUtil.FileDirType.ZHANGHAN_TEST);
} catch (Exception e) {
LoggerUtil.logService(LoggerUtil.spManualLoan, "SPManualLoanServiceImpl-submitLoan", "call OSSUtil.upload; Exception:" + e.getMessage());
throw new BusinessException(WrongMessageEnum.EXCEPTION_STORE);
}
return uploadResult;
}

       3、问题&解决:

          (1) 问题:通过URL在浏览器中访问时报如下错:

  

          (2)解决方案:在阿里云的控制台上,进入OSS的设置界面,将Bucket的访问权限由 私有 设置为 公共读

【总结】

       阿里云现在很多公司都在用,阿里云稳定,安全,相对来说成本更低;给自己更多思考的是如何让项目减少成本,以及阿里云等带来的商业模式。

你可能感兴趣的文章
《趣学Python——教孩子学编程》——1.5 你学到了什么
查看>>
《提高转化率!网页A/B测试与多变量测试实战指南》一2.5 勇气与责任心
查看>>
深入实践Spring Boot3.2 控制器设计
查看>>
《微信小程序:开发入门及案例详解》—— 导读
查看>>
降低JRuby的内存占用的可能方法
查看>>
如何创建和使用Python CGI脚本
查看>>
RHCSA 系列(九): 安装、配置及加固一个 Web 和 FTP 服务器
查看>>
程序员专属健身操,大家一起动次打次浪起来!
查看>>
《jQuery、jQuery UI及jQuery Mobile技巧与示例》——3.7 示例:添加函数的返回结果...
查看>>
并发集合(一)引言
查看>>
如何写gdb命令脚本
查看>>
Android ListView展示不同的布局
查看>>
oracle 表(下)
查看>>
iOS宏(自己使用,持续更新)
查看>>
手把手玩转win8开发系列课程(3)
查看>>
NGINX引入线程池 性能提升9倍
查看>>
《淘宝技术这十年》读书笔记 (四). 分布式时代和中间件
查看>>
linux下mongodb定时备份指定的集合
查看>>
GNU Radio中流图的动态配置
查看>>
SMP架构多线程程序的一种性能衰退现象—False Sharing
查看>>