阿里云OSS工具类

【前言】

我们上家公司的存储系统用的是FastDFS(智能一代云平台(二十八):对前后端分离和FastDFS的使用的再理解);现在在职的公司用的是阿里云的OSS(OSS的官方文档),在工作的时候整理一个上传OSS文件的工具类,现在与大家分享一下。

【工具类】

1、工具类的代码:


  1. package zhanghan.oss.utils;
  2. import com.aliyun.oss.ClientException;
  3. import com.aliyun.oss.OSSClient;
  4. import com.aliyun.oss.OSSException;
  5. import com.aliyun.oss.model.ObjectMetadata;
  6. import com.aliyun.oss.model.PutObjectResult;
  7. import com.fasterxml.jackson.annotation.JsonValue;
  8. import org.apache.commons.io.FilenameUtils;
  9. import org.apache.commons.lang3.time.DateUtils;
  10. import org.springframework.util.StringUtils;
  11. import org.springframework.web.multipart.MultipartFile;
  12. import zhanghan.oss.exception.OSSCreateBucketRuntimeException;
  13. import zhanghan.oss.exception.OSSGeneratePresignedUrlRuntimeException;
  14. import zhanghan.oss.exception.OssPutObjectRuntimeException;
  15. import java.io.InputStream;
  16. import java.net.URL;
  17. import java.util.Date;
  18. import java.util.UUID;
  19. /**
  20. * OSS上传工具类-张晗-2017/10/10
  21. */
  22. public class OSSUtil {
  23. private volatile static OSSClient instance;
  24. private OSSUtil() {
  25. }
  26. /**
  27. * 单例
  28. * @return OSS工具类实例
  29. */
  30. private static OSSClient getOSSClient() {
  31. if (instance == null) {
  32. synchronized (OSSUtil.class) {
  33. if (instance == null) {
  34. instance = new OSSClient(OSS_END_POINT, OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET);
  35. }
  36. }
  37. }
  38. return instance;
  39. }
  40. //定义日志
  41. private final static LogUtils logger = LogUtils.getLogger(OSSUtil.class);
  42. //OSS 的地址
  43. private final static String OSS_END_POINT = "http://oss-cn-qingdao.aliyuncs.com";
  44. //OSS 的key值
  45. private final static String OSS_ACCESS_KEY_ID = "OSSKEY";
  46. //OSS 的secret值
  47. private final static String OSS_ACCESS_KEY_SECRET = "OSSSECRET";
  48. //OSS 的bucket名字
  49. private final static String OSS_BUCKET_NAME = "zhanghan-test";
  50. //设置URL过期时间为10年
  51. private final static Date OSS_URL_EXPIRATION = DateUtils.addDays(new Date(), 365 * 10);
  52. //文件路径的枚举
  53. public enum FileDirType {
  54. ZHANGHAN_TEST("test");
  55. private String dir;
  56. FileDirType(String dir) {
  57. this.dir = dir;
  58. }
  59. @JsonValue
  60. public String getDir() {
  61. return dir;
  62. }
  63. }
  64. /**
  65. * 上传文件---去除URL中的?后的时间戳
  66. * @param file 文件
  67. * @param fileDir 上传到OSS上文件的路径
  68. * @return 文件的访问地址
  69. */
  70. public static String upload(MultipartFile file, FileDirType fileDir) {
  71. OSSUtil.createBucket();
  72. String fileName = OSSUtil.uploadFile(file, fileDir);
  73. String fileOssURL = OSSUtil.getImgUrl(fileName, fileDir);
  74. int firstChar = fileOssURL.indexOf("?");
  75. if (firstChar > 0) {
  76. fileOssURL = fileOssURL.substring(0, firstChar);
  77. }
  78. return fileOssURL;
  79. }
  80. /**
  81. * 当Bucket不存在时创建Bucket
  82. *
  83. * @throws OSSException 异常
  84. * @throws ClientException Bucket命名规则:
  85. * 1.只能包含小写字母、数字和短横线,
  86. * 2.必须以小写字母和数字开头和结尾
  87. * 3.长度在3-63之间
  88. */
  89. private static void createBucket() {
  90. try {
  91. if (!OSSUtil.getOSSClient().doesBucketExist(OSS_BUCKET_NAME)) {//判断是否存在该Bucket,不存在时再重新创建
  92. OSSUtil.getOSSClient().createBucket(OSS_BUCKET_NAME);
  93. }
  94. } catch (Exception e) {
  95. logger.error("{}", "创建Bucket失败,请核对Bucket名称(规则:只能包含小写字母、数字和短横线,必须以小写字母和数字开头和结尾,长度在3-63之间)");
  96. throw new OSSCreateBucketRuntimeException("创建Bucket失败,请核对Bucket名称(规则:只能包含小写字母、数字和短横线,必须以小写字母和数字开头和结尾,长度在3-63之间)");
  97. }
  98. }
  99. /**
  100. * 上传到OSS服务器 如果同名文件会覆盖服务器上的
  101. * @param file 文件
  102. * @param fileDir 上传到OSS上文件的路径
  103. * @return 文件的访问地址
  104. */
  105. private static String uploadFile(MultipartFile file, FileDirType fileDir) {
  106. String fileName = String.format(
  107. "%s.%s",
  108. UUID.randomUUID().toString(),
  109. FilenameUtils.getExtension(file.getOriginalFilename()));
  110. try (InputStream inputStream = file.getInputStream()) {
  111. //创建上传Object的Metadata
  112. ObjectMetadata objectMetadata = new ObjectMetadata();
  113. objectMetadata.setContentLength(inputStream.available());
  114. objectMetadata.setCacheControl("no-cache");
  115. objectMetadata.setHeader("Pragma", "no-cache");
  116. objectMetadata.setContentType(getContentType(FilenameUtils.getExtension("." + file.getOriginalFilename())));
  117. objectMetadata.setContentDisposition("inline;filename=" + fileName);
  118. //上传文件
  119. PutObjectResult putResult = OSSUtil.getOSSClient().putObject(OSS_BUCKET_NAME, fileDir.getDir() + fileName, inputStream, objectMetadata);
  120. return fileName;
  121. } catch (Exception e) {
  122. logger.error("{}", "上传文件失败");
  123. throw new OssPutObjectRuntimeException("上传文件失败");
  124. }
  125. }
  126. /**
  127. * 获得文件路径
  128. * @param fileUrl 文件的URL
  129. * @param fileDir 文件在OSS上的路径
  130. * @return 文件的路径
  131. */
  132. private static String getImgUrl(String fileUrl, FileDirType fileDir) {
  133. if (StringUtils.isEmpty(fileUrl)) {
  134. logger.error("{}", "文件地址为空");
  135. throw new RuntimeException("文件地址为空");
  136. }
  137. String[] split = fileUrl.split("/");
  138. //获取oss图片URL失败
  139. URL url = OSSUtil.getOSSClient().generatePresignedUrl(OSS_BUCKET_NAME, fileDir.getDir() + split[split.length - 1], OSS_URL_EXPIRATION);
  140. if (url == null) {
  141. logger.error("{}", "获取oss文件URL失败");
  142. throw new OSSGeneratePresignedUrlRuntimeException("获取oss文件URL失败");
  143. }
  144. return url.toString();
  145. }
  146. /**
  147. * 判断OSS服务文件上传时文件的contentType
  148. *
  149. * @param FilenameExtension 文件后缀
  150. * @return 后缀
  151. */
  152. private static String getContentType(String FilenameExtension) {
  153. if (FilenameExtension.equalsIgnoreCase("bmp")) {
  154. return "image/bmp";
  155. }
  156. if (FilenameExtension.equalsIgnoreCase("gif")) {
  157. return "image/gif";
  158. }
  159. if (FilenameExtension.equalsIgnoreCase("jpeg") ||
  160. FilenameExtension.equalsIgnoreCase("jpg") ||
  161. FilenameExtension.equalsIgnoreCase("png")) {
  162. return "image/jpeg";
  163. }
  164. if (FilenameExtension.equalsIgnoreCase("html")) {
  165. return "text/html";
  166. }
  167. if (FilenameExtension.equalsIgnoreCase("txt")) {
  168. return "text/plain";
  169. }
  170. if (FilenameExtension.equalsIgnoreCase("vsd")) {
  171. return "application/vnd.visio";
  172. }
  173. if (FilenameExtension.equalsIgnoreCase("pptx") ||
  174. FilenameExtension.equalsIgnoreCase("ppt")) {
  175. return "application/vnd.ms-powerpoint";
  176. }
  177. if (FilenameExtension.equalsIgnoreCase("docx") ||
  178. FilenameExtension.equalsIgnoreCase("doc")) {
  179. return "application/msword";
  180. }
  181. if (FilenameExtension.equalsIgnoreCase("xml")) {
  182. return "text/xml";
  183. }
  184. return "image/jpeg";
  185. }
  186. }

2、调用工具类的代码:


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

3、问题&解决:

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

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

【总结】

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

原文地址:https://www.cnblogs.com/jpfss/p/10146505.html

时间: 2024-10-29 06:38:12

阿里云OSS工具类的相关文章

上传图片到阿里云OSS和获取上传图片的外网url的步骤

<form action="/bcis/api/headImgUpload.json" method="post" enctype="multipart/form-data">     <input type="file" name="file">     <input type="submit" value="提交"> </

iOS使用阿里云OSS对象存储 (SDK 2.1.1)

最近项目中用到了阿里云OSS对象存储,用来存储APP中图片.音频等一些数据.但坑爹的阿里云居然在11月20日将SDK版本更新到了2.1.1,然而网上给出的教程都是1.*版本的(针对iOS),两个版本所调用的方法差别较大(自我感觉),当然原理都一样.所以看了两天SDK,自己封装了几个常用的方法. 一.OSS简单介绍 OSS是提供非结构化数据存取的服务,非结构化数据一般包括图片.文档.音频.视频等一些文件.OSS提供了接口,开发者可以通过这些接口对数据进行上传或下载等操作. 开通OSS服务后,创建一

Java中使用RestFul接口上传图片到阿里云OSS服务器

1.接口方法 import java.io.IOException; import javax.servlet.http.HttpServletRequest; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation

thinkphp集成系列之阿里云oss

web2.0时代:除了纯信息展示类的网站:基本都是有文件上传功能的: 最不济你得让用户换个头像吧:但是随着业务的发展: 如果上传的文件都和网站程序源代码放在一起:那是有相当多的弊端的: 1:静态文件会占用大量带宽: 2:服务器的成本略高: 常规的做法是把php源代码放到一台服务器上:图片等静态文件放在另一台服务器上: 当一个神奇的“云”时代的到来后:一切就变的更加简单了: 在业务还比较小的时候:我们无需大费周折的去搞一台静态文件服务器:直接使用第三方的即可: 好了:洛里啰嗦了半天:下面请出本篇博

发布阿里云OSS for phpcmsV9整合教程

说明:这个算不上是插件,因为没有安装包,需要手工修改代码. 还有一点就是后台发布文章时上传的附件还是会保存在你的服务器上,基于以下原因: 1.个人的需求是前台页面需要使用thumb函数生成多个缩略图大小,thumb函数是不支持远程图片的(保存在OSS上就变远程图片了),即使修改为支持远程图片,也需要将远程图片先保存到本地,这样速度会非常慢,是非常非常: 2.做备份的需要,这点你懂得,某天OSS上的附件没有了就悲剧了,所以使用这个OSS for phpcmsV9需要服务器有一定的空间. 下面是整合

Aliyun OSS Nginx proxy module(阿里云OSS Nginx 签名代理模块)

1.此文章主要介绍内容 本文主要介绍怎样利用Nginx lua 实现将阿里云OSS存储空间做到同本地磁盘一样使用.核心是利用Nginx lua 对OSS请求进行签名并利用内部跳转将全部訪问本地Nginx的请求加上OSS 签名转发给OSS,实现本地Nginx无缝衔接阿里云OSS,存储空间无限扩展,存储成本无限下降,数据安全%99.99-- . 2.本篇文章使用到的一些工具技术及怎样学习和获取 1.lua 本文用到的都是一些主要的lua,基本上花半小时阅读下lua的语法就能够轻松理解本文内容 2.N

在OneThink(ThinkPHP3.2.3)中整合阿里云OSS的PHP-SDK2.0.4,实现Web端直传,服务端签名直传并设置上传回调的实现流程

在OneThink(ThinkPHP3.2.3)中整合阿里云OSS的PHP-SDK2.0.4,实现本地文件上传流程 by shuijingwan · 2016/01/13 1.SDK安装 github地址:https://github.com/aliyun/aliyun-oss-php-sdk 2.复制aliyun-oss-php-sdk-master\src\OSS至passport.hmwis.com\ThinkPHP\Library\Vendor\OSS,如图1.2 复制aliyun-os

上传图片到阿里云OSS的步骤

啥都不说  直接上代码 1.html: <form action="/bcis/api/headImgUpload.json" method="post" enctype="multipart/form-data"> <input type="file" name="file"> <input type="submit" value="提交&quo

阿里云oss上传图片

1.首先我们要下载阿里云oss的sdk包:(可以下载原版的,改过的通用版在本人的百度云,嘎嘎嘎~) 2.下载好之后放到项目文件目录里面 3.要在需要的控制器引用这个sdk文件例如: include("./ThinkPHP/Library/Vendor/oss/index.php"); 然后实例化这个类,调用上传的方法 =================================================== 再看类文件:下载好了以后修改类文件的index.php <?