阿里云OSS工具类
【前言】
我们上家公司的存储系统用的是FastDFS(智能一代云平台(二十八):对前后端分离和FastDFS的使用的再理解);现在在职的公司用的是阿里云的OSS(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的访问权限由 私有 设置为 公共读
【总结】
阿里云现在很多公司都在用,阿里云稳定,安全,相对来说成本更低;给自己更多思考的是如何让项目减少成本,以及阿里云等带来的商业模式。
阿里云OSS工具类的更多相关文章
- Linux目录同步到阿里云OSS工具ossutil
Linux目录同步到阿里云OSS工具ossutil 背景 最近公司服务用户激增,常规文件服务器不能满足需求,严重影响性能,决定将静态文件迁移到阿里云OSS,用来解决性能问题,提高用户体验.毕竟之前 ...
- 小白的springboot之路(十七)、阿里云OSS 的使用
0-前言 项目中,文件服务必不可少,常用的有各云服务商的OSS服务(如阿里云OSS,腾讯云OSS,七牛云).自建(fastDFS.minio): 推荐:如果用云服务的话,阿里云OSS很方便,如果自建的 ...
- JAVA整合阿里云OSS实现文件上传功能
引入maven <dependency> <groupId>org.apache.commons</groupId> <artifactId>commo ...
- 上传图片到阿里云OSS和获取上传图片的外网url的步骤
啥都不说 直接上代码 1.html: <form action="/bcis/api/headImgUpload.json" method="post" ...
- 一招教你写博客,Typora+PicGo+阿里云oss,最好用的Markdown+最好用的图床工具!
博客 写博客的好处 1.使自己变得更善于观察.一旦你养成了记博客的习惯,与此同时你也赋予了一个更好的机会给自己,让自己去更细致地观察生活.一个人的生活经历本就是价值连城的,从中学习到的知识,教训更是异 ...
- iOS使用阿里云OSS对象存储 (SDK 2.1.1)
最近项目中用到了阿里云OSS对象存储,用来存储APP中图片.音频等一些数据.但坑爹的阿里云居然在11月20日将SDK版本更新到了2.1.1,然而网上给出的教程都是1.*版本的(针对iOS),两个版本所 ...
- 构建基于阿里云OSS文件上传服务
转载请注明来源:http://blog.csdn.net/loongshawn/article/details/50710132 <构建基于阿里云OSS文件上传服务> <构建基于OS ...
- Java下载https文件上传到阿里云oss服务器
Java下载https文件上传到阿里云oss服务器 今天做了一个从Https链接中下载音频并且上传到OSS服务器,记录一下希望大家也少走弯路. 一共两个类: 1 .实现自己的证书信任管理器类 /** ...
- Java中使用RestFul接口上传图片到阿里云OSS服务器
1.接口方法 import java.io.IOException; import javax.servlet.http.HttpServletRequest; import org.springfr ...
随机推荐
- Intellij IDEA中修改项目名称
如下图红色标识所示: 修改方法见下图:
- PLSQL乱码&TNS-12557: protocol adapter not loadable解决
PLSQL乱码&TNS-12557: protocol adapter not loadable解决 PLSQL乱码&TNS-12557: protocol adapter not l ...
- 程序猿的量化交易之路(14)--Cointrader数据表(2)
Cointrader表结构 转载须注明出处:http://blog.csdn.net/minimicall?viewmode=contents,http://cloudtrader.top 设置(se ...
- elasticsearch transport 请求发送和处理
前一篇分析对nettytransport的启动及连接,本篇主要分析transport请求的发送和处理过程.cluster中各个节点之间需要相互发送很多信息,如master检测其它节点是否存在,node ...
- Linux 内存管理与系统架构设计
Linux 提供各种模式(比如,消息队列),但是最著名的是 POSIX 共享内存(shmem,shared memory). Linux provides a variety of schemes ( ...
- Android 在滚动列表中实现视频的播放(ListView & RecyclerView)
这片文章基于开源项目: VideoPlayerManager. 所有的代码和示例都在那里.本文将跳过许多东西.因此如果你要真正理解它是如何工作的,最好下载源码,并结合源代码一起阅读本文.但是即便是没有 ...
- 3.字符设备驱动------Poll机制
1.poll情景描述 以之前的按键驱动为例进行说明,用阻塞的方式打开按键驱动文件/dev/buttons,应用程序使用read()函数来读取按键的键值. ) { read(fd, &key_v ...
- hdu4605Magic Ball Game 树状数组
//给一棵树.树的每个节点的子节点个数是0或2 //对于每个节点都有一个权值w[i] //一个权值为x的球在每个节点的情况有 //x=w[i] 这个球在该点不向下掉 //x<w[i] 这个球往左 ...
- c# 调用 C++ dll 传入传出 字符串
c# 调用 C++ dll 传入传出 字符串 2013-07-02 09:30 7898人阅读 评论(2) 收藏 举报 本文章已收录于: 分类: windows 版权声明:随便转载,随便使用. C ...
- crm翻译导航栏
在crm里面怎样翻译导航栏? 过程例如以下: 1 先新建一个解决方式.把网站地图加进去 2: 然后把这个解决方式到出来来,解压文件: 3:编辑第二个文件: watermark/2/text/aHR0c ...