阿裏雲OSS工具類
阿新 • • 發佈:2018-12-20
src lsi uuid csdn pack sso wrong ews 商業模式
【前言】
我們上家公司的存儲系統用的是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工具類