專案啟動的要加上配置檔案的掃描路徑
import com.example.config.ObsProperties; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.EnableConfigurationProperties; @MapperScan("com.example.dao") @SpringBootApplication @EnableConfigurationProperties({ObsProperties.class}) public class DemoApplication { public static void main(String[] args) { System.out.println("----------服務開始啟動----------"); SpringApplication.run(VirtualNumberApplication.class, args); System.out.println("-----------服務啟動成功----------"); } }
ObsProperties
在專案啟動的時候初始化HuaWeiOBSUtil類
import com.example.utils.HuaWeiOBSUtil; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; /** * @description: 華為雲OBS配置資訊 */ @ConfigurationProperties(prefix = "obs") public class ObsProperties { private String domainName; private String bucketName; private String accessKeyId; private String accessKeySecret; private String endPoint; private String privateFile; public String getDomainName() { return domainName; } public void setDomainName(String domainName) { this.domainName = domainName; } public String getBucketName() { return bucketName; } public void setBucketName(String bucketName) { this.bucketName = bucketName; } 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 getEndPoint() { return endPoint; } public void setEndPoint(String endPoint) { this.endPoint = endPoint; } public String getPrivateFile() { return privateFile; } public void setPrivateFile(String privateFile) { this.privateFile = privateFile; } @Bean public HuaWeiOBSUtil huaWeiOBSUtil() { return new HuaWeiOBSUtil(bucketName, accessKeyId, accessKeySecret, endPoint, privateFile); } }
HuaWeiOBSUtil
package com.example.utils; import com.exampleenums.IntegerValueEnum; import com.example.enums.StringEnum; import com.obs.services.ObsClient; import com.obs.services.exception.ObsException; import com.obs.services.model.*; import io.micrometer.common.util.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.multipart.MultipartFile; import java.io.*; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.UUID; /** * @description: 華為雲OBS工具類 */ public class HuaWeiOBSUtil { /*** 檔案外鏈過期時間,7天 */ private static long expire = 7 * 24 * 60 * 60; /*** 檔案外鏈訪問埠 */ private static String port = ":443"; private static String bucketName; private static String ak; private static String sk; private static String endPoint; private static String privateFile; /*** OBS操作客戶端 */ private static ObsClient obsClient = null; private static final String SEPARATOR = StringEnum.STRING_RIGHT_SLASH.getValue(); private static Logger log = LoggerFactory.getLogger(HuaWeiOBSUtil.class); public HuaWeiOBSUtil(String bucketName, String ak, String sk, String endPoint, String privateFile) { HuaWeiOBSUtil.bucketName = bucketName; HuaWeiOBSUtil.ak = ak; HuaWeiOBSUtil.sk = sk; HuaWeiOBSUtil.endPoint = endPoint; HuaWeiOBSUtil.privateFile = privateFile; createObsClientInstance(); } public static String getBucketName() { return bucketName; } public static String getAk() { return ak; } public static String getSk() { return sk; } public static String getEndPoint() { return endPoint; } /** * 獲取OBS操作客戶端 */ private static void createObsClientInstance() { synchronized (ObsClient.class) { try { if (obsClient == null) { obsClient = new ObsClient(ak, sk, endPoint); } createBucket(bucketName, endPoint); } catch (Exception e) { log.error("連線華為雲端儲存伺服器異常:" + e.getMessage(), e); } } } /** * 建立儲存桶 * * @param bucketName * @param endPoint */ public static void createBucket(String bucketName, String endPoint) { try { if (!headBucket(bucketName)) { CreateBucketRequest request = new CreateBucketRequest(); // 設定儲存桶名稱 request.setBucketName(bucketName); // 設定桶區域位置,從endPoint中擷取,如果Location設定的區域與endPoint中的區域不是同一個,則建立會報錯 request.setLocation(getRegion(endPoint)); // 設定桶訪問許可權為公共讀,預設是私有讀寫 request.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ); // 建立桶成功 ObsBucket bucket = obsClient.createBucket(request); log.info("建立桶成功,返回RequestId:{}", bucket.getRequestId()); } } catch (ObsException e) { // 建立桶失敗 log.error("HTTP Code: {}", e.getResponseCode()); log.error("Error Code: {}", e.getErrorCode()); log.error("Error Message: {}", e.getErrorMessage()); log.error("Request ID: {}", e.getErrorRequestId()); log.error("Host ID: {}", e.getErrorHostId()); } } public AccessControlList getObjectAcl(String objectName) { AccessControlList objectAcl = obsClient.getObjectAcl(bucketName, objectName); return objectAcl; } /** * 獲取上傳檔案的基礎路徑 * * @return */ public static String getBasisUrl() { // 實示例:http協議 + 儲存桶名稱 + . + endPoint + port + / return getHttpProtocol(endPoint) + StringEnum.STRING_TWO_RIGHT_SLASH.getValue() + bucketName + StringEnum.STRING_POINT.getValue() + endPoint .replace(getHttpProtocol(endPoint) + StringEnum.STRING_TWO_RIGHT_SLASH.getValue(), StringEnum.STRING_EMPTY.getValue()) + port + SEPARATOR; } /** * 獲取上傳檔案的基礎路徑 * * @param bucketName * @return */ public static String getBasisUrl(String bucketName) { // 實示例:http協議 + 儲存桶名稱 + . + endPoint + port + / return getHttpProtocol(endPoint) + StringEnum.STRING_TWO_RIGHT_SLASH.getValue() + bucketName + StringEnum.STRING_POINT.getValue() + endPoint .replace(getHttpProtocol(endPoint) + StringEnum.STRING_TWO_RIGHT_SLASH.getValue(), StringEnum.STRING_EMPTY.getValue()) + port + SEPARATOR; } /** * 獲取區域 * * @param endPoint * @return */ public static String getRegion(String endPoint) { String substring = endPoint.substring(endPoint.indexOf(StringEnum.STRING_POINT.getValue()) + IntegerValueEnum.ONE.getValue()); return substring.substring(IntegerValueEnum.ZERO.getValue(), substring.indexOf(StringEnum.STRING_POINT.getValue())); } /** * 獲取http協議 * * @param endPoint * @return */ public static String getHttpProtocol(String endPoint) { return endPoint.substring(IntegerValueEnum.ZERO.getValue(), endPoint.indexOf(StringEnum.STRING_COLON.getValue())); } /*** * 刪除儲存桶** @param bucketName* * * @return */ public static HeaderResponse deleteBucket(String bucketName) { return obsClient.deleteBucket(bucketName); } /*** * 判斷儲存桶是否存在** @param bucketName* * * @return */ public static boolean headBucket(String bucketName) { return obsClient.headBucket(bucketName); } /** * 上傳字元 * * @param bucketName * @param objectName * @param content * @return */ public static PutObjectResult putObjectByStr(String bucketName, String objectName, String content) { if (StringUtils.isBlank(content)) { return null; } // 重新構建objectName objectName = buildObjectName(objectName); return obsClient.putObject(bucketName, objectName, new ByteArrayInputStream(content.getBytes())); } /** * 上傳byte * * @param bucketName * @param objectName * @param content * @return */ public static PutObjectResult putObjectByByte(String bucketName, String objectName, byte[] content, String fileName) { return putObjectByInput(bucketName, objectName, new ByteArrayInputStream(content), fileName); } /** * 上傳byte * * @param bucketName * @param objectName * @param content * @return */ public static PutObjectResult putPrivateObjectByByte(String bucketName, String objectName, byte[] content, String fileName) { return putObjectByInput(bucketName, objectName, new ByteArrayInputStream(content), fileName); } /** * 上傳輸入流 * * @param bucketName * @param objectName * @param inputStream * @return */ public static PutObjectResult putObjectByInput(String bucketName, String objectName, InputStream inputStream, String fileName) { String acl = "private"; // 重新構建objectName objectName = buildObjectName(objectName); PutObjectRequest putObjectRequest = setObjectMetadata(bucketName, objectName, fileName, acl); putObjectRequest.setInput(inputStream); return obsClient.putObject(putObjectRequest); } /** * 上傳檔案輸入流 * * @param bucketName * @param objectName * @param fileInputStream * @return */ public static PutObjectResult putObjectByFileInput(String bucketName, String objectName, FileInputStream fileInputStream) { // 重新構建objectName objectName = buildObjectName(objectName); return obsClient.putObject(bucketName, objectName, fileInputStream); } /** * 透過MultipartFile,上傳檔案 * * @param bucketName * @param objectName * @param media * @return * @throws IOException */ public static PutObjectResult putObjectByMultipartFile(String bucketName, String objectName, MultipartFile media) throws IOException { // 重新構建objectName objectName = buildObjectName(objectName); return obsClient.putObject(bucketName, objectName, media.getInputStream()); } /** * 上傳本地檔案 * * @param bucketName * @param objectName 上傳儲存的路徑 * @param file * @return */ public static PutObjectResult putObjectByFile(String bucketName, String objectName, File file, String acl) { // 重新構建objectName objectName = buildObjectName(objectName); PutObjectRequest putObjectRequest = setObjectMetadata(bucketName, objectName, file.getName(), acl); putObjectRequest.setFile(file); return obsClient.putObject(putObjectRequest); } /** * 下載檔案到本地 * * @param bucketName * @param objectName * @param filePath * @return * @throws Exception */ public static boolean downloadObject(String bucketName, String objectName, String filePath) throws Exception { if (StringUtils.isBlank(filePath)) { return false; } // 重新構建objectName objectName = buildObjectName(objectName); filePath = filePath.replace("\\", SEPARATOR); InputStream input = null; FileOutputStream fileOutputStream = null; try { // 獲取物件 ObsObject obsObject = obsClient.getObject(bucketName, objectName); // 讀取物件內容 input = obsObject.getObjectContent(); if (input == null) { return false; } // 獲取資料夾路徑 if (filePath.contains(SEPARATOR)) { String dir = filePath.substring(IntegerValueEnum.ZERO.getValue(), filePath.lastIndexOf(SEPARATOR)); File difFile = new File(dir); if (!difFile.exists()) { // 建立資料夾 boolean mkdirs = difFile.mkdirs(); } } File file = new File(filePath); fileOutputStream = new FileOutputStream(file); byte[] b = new byte[1024]; int len; while ((len = input.read(b)) != IntegerValueEnum.NEGATIVE_ONE.getValue()) { fileOutputStream.write(b, IntegerValueEnum.ZERO.getValue(), len); } return true; } finally { if (fileOutputStream != null) { fileOutputStream.close(); } if (input != null) { input.close(); } } } /** * 獲取檔案內容 * * @param bucketName * @param objectName * @return * @throws IOException */ public static String getObjectContent(String bucketName, String objectName) throws IOException { // 重新構建objectName objectName = buildObjectName(objectName); InputStream input = null; ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { ObsObject obsObject = obsClient.getObject(bucketName, objectName); // 讀取物件內容 input = obsObject.getObjectContent(); byte[] b = new byte[1024]; int len; while ((len = input.read(b)) != IntegerValueEnum.NEGATIVE_ONE.getValue()) { bos.write(b, IntegerValueEnum.ZERO.getValue(), len); } return new String(bos.toByteArray()); } finally { bos.close(); if (input != null) { input.close(); } } } /** * 獲取檔案輸入流 * * @param bucketName * @param objectName * @return */ public static InputStream getObject(String bucketName, String objectName) { // 重新構建objectName objectName = buildObjectName(objectName); return obsClient.getObject(bucketName, objectName).getObjectContent(); } /** * 指定數目和字首列舉 * * @param bucketName * @param prefix * @param maxKeys * @return */ public static List<ObsObject> listObjects(String bucketName, String prefix, Integer maxKeys) { prefix = prefix.startsWith(StringEnum.STRING_RIGHT_SLASH.getValue()) ? prefix.substring(IntegerValueEnum.ONE.getValue()) : prefix; ListObjectsRequest request = new ListObjectsRequest(bucketName); // 設定列舉的物件個數 request.setMaxKeys(maxKeys); // 設定列舉的物件需要帶有指定字首 request.setPrefix(prefix); ObjectListing result = obsClient.listObjects(request); return result.getObjects(); } /** * 列舉指定字首的全部物件 * * @param bucketName * @param prefix * @return */ public static List<ObsObject> listAllObjects(String bucketName, String prefix) { prefix = prefix.startsWith(StringEnum.STRING_RIGHT_SLASH.getValue()) ? prefix.substring(IntegerValueEnum.ONE.getValue()) : prefix; List<ObsObject> list = new ArrayList<>(); ListObjectsRequest request = new ListObjectsRequest(bucketName); // 設定列舉的物件個數 request.setMaxKeys(1000); // 設定列舉的物件需要帶有指定字首 request.setPrefix(prefix); ObjectListing result; do { result = obsClient.listObjects(request); request.setMarker(result.getNextMarker()); list.addAll(result.getObjects()); } while (result.isTruncated()); return list; } /** * 刪除單個物件 * * @param bucketName * @param objectName * @return */ public static DeleteObjectResult deleteObject(String bucketName, String objectName) { // 重新構建objectName objectName = buildObjectName(objectName); return obsClient.deleteObject(bucketName, objectName); } /** * 複製物件 * * @param sourceBucketName * @param sourceObjectName * @param destBucketName * @param destObjectName * @return */ public static CopyObjectResult copyObject(String sourceBucketName, String sourceObjectName, String destBucketName, String destObjectName) { return obsClient.copyObject(sourceBucketName, sourceObjectName, destBucketName, destObjectName); } /** * 複製物件 * * @param sourceBucketName * @param sourceObjectName * @param destBucketName * @param destObjectName * @return */ public static CopyObjectResult copyObject1(String sourceBucketName, String sourceObjectName, String destBucketName, String destObjectName) { // 重新構建objectName sourceObjectName = buildObjectName(sourceObjectName); destObjectName = buildObjectName(destObjectName); return obsClient.copyObject(sourceBucketName, sourceObjectName, destBucketName, destObjectName); } /** * 判斷物件是否存在 * * @param bucketName * @param objectName * @return */ public static boolean doesObjectExist(String bucketName, String objectName) { // 重新構建objectName objectName = buildObjectName(objectName); return obsClient.doesObjectExist(bucketName, objectName); } /** * 獲取檔案外鏈 * * @param bucketName * @param objectName * @param expires 大於等於0的整型數,單位:秒 * @return */ public static String getSignedUrl(String bucketName, String objectName, Long expires) { // 重新構建objectName objectName = buildObjectName(objectName); TemporarySignatureRequest request = new TemporarySignatureRequest(HttpMethodEnum.GET, expires); request.setBucketName(bucketName); request.setObjectKey(objectName); TemporarySignatureResponse response = obsClient.createTemporarySignature(request); return response.getSignedUrl(); } /** * 獲取檔案外鏈-url有效時間預設7天 * * @param bucketName * @param objectName * @return */ public static String getSignedUrl(String bucketName, String objectName) { return getSignedUrl(bucketName, objectName, expire); } /** * 重新構建objectName * * @param objectName * @return */ private static String buildObjectName(String objectName) { if (StringUtils.isBlank(objectName)) { return objectName; } // 去除開頭的/ objectName = objectName.startsWith(StringEnum.STRING_RIGHT_SLASH.getValue()) ? objectName.substring(IntegerValueEnum.ONE.getValue()) : objectName; // 去除?後邊的引數 objectName = objectName.contains(StringEnum.STRING_QUESTION.getValue()) ? objectName.substring(IntegerValueEnum.ZERO.getValue(), objectName.indexOf(StringEnum.STRING_QUESTION.getValue())) : objectName; return objectName; } /** * 傳入檔案訪問外鏈,返回objectName * * @param url * @return */ public static String getObjectNameByUrl(String url) { if (StringUtils.isBlank(url)) { return url; } if (url.contains(getBasisUrl())) { // 去除minio基礎路徑 url = url.replace(getBasisUrl(), StringEnum.STRING_EMPTY.getValue()); // 去除?後邊的引數 url = url.contains(StringEnum.STRING_QUESTION.getValue()) ? url.substring(IntegerValueEnum.ZERO.getValue(), url.indexOf(StringEnum.STRING_QUESTION.getValue())) : url; } return url; } public static String getContentType(String fileName) { // 檔案的字尾名 if (fileName.lastIndexOf(StringEnum.STRING_POINT.getValue()) < IntegerValueEnum.ZERO.getValue()) { // 預設返回型別 return StringEnum.STRING_EMPTY.getValue(); } String fileExtension = fileName.substring(fileName.lastIndexOf(StringEnum.STRING_POINT.getValue())); if (".bmp".equalsIgnoreCase(fileExtension)) { return "image/bmp"; } if (".gif".equalsIgnoreCase(fileExtension)) { return "image/gif"; } if (".jpeg".equalsIgnoreCase(fileExtension) || ".jpg".equalsIgnoreCase(fileExtension) || ".png".equalsIgnoreCase(fileExtension)) { return "image/jpeg"; } if (".png".equalsIgnoreCase(fileExtension)) { return "image/png"; } if (".html".equalsIgnoreCase(fileExtension)) { return "text/html"; } if (".txt".equalsIgnoreCase(fileExtension)) { return "text/plain"; } if (".vsd".equalsIgnoreCase(fileExtension)) { return "application/vnd.visio"; } if (".ppt".equalsIgnoreCase(fileExtension) || "pptx".equalsIgnoreCase(fileExtension)) { return "application/vnd.ms-powerpoint"; } if (".doc".equalsIgnoreCase(fileExtension) || "docx".equalsIgnoreCase(fileExtension)) { return "application/msword"; } if (".xml".equalsIgnoreCase(fileExtension)) { return "text/xml"; } // 預設返回型別 return StringEnum.STRING_EMPTY.getValue(); } /** * 獲取檔案路徑 * * @param profiles * @param fileName * @return */ public static String getFilePath(String profiles, String fileName) { String acl = "private"; // 獲取檔案字尾 String suffix = fileName.substring(fileName.lastIndexOf(StringEnum.STRING_POINT.getValue())); // 按時間生產一個目錄 String date = DateUtils.dateToString(new Date(), "yyyyMMdd"); StringBuffer buffer = new StringBuffer(); if (StringUtils.isNotEmpty(acl) && AccessControlList.REST_CANNED_PRIVATE.equals(convertAcl(acl))) { buffer.append(privateFile); } buffer.append(profiles).append(StringEnum.STRING_RIGHT_SLASH.getValue()).append(date) .append(StringEnum.STRING_RIGHT_SLASH.getValue()); buffer.append(UUID.randomUUID().toString().replace(StringEnum.STRING_MINUS.getValue(), StringEnum.STRING_EMPTY.getValue())) .append(suffix); return buffer.toString(); } /** * 獲取檔案訪問地址 * * @param acl * @param filePath * @return */ public static String getFileUrl(String filePath, Long expires) { filePath = getSignedUrl(bucketName, filePath, expires); return filePath; } /** * 設定上傳物件屬性許可權 * * @param fileName * @param acl * @return */ public static PutObjectRequest setObjectMetadata(String bucketName, String objectName, String fileName, String acl) { PutObjectRequest request = new PutObjectRequest(); ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentType(getContentType(fileName)); request.setMetadata(metadata); // 設定檔案訪問許可權 這裡是私有 if (StringUtils.isNotEmpty(acl) && AccessControlList.REST_CANNED_PRIVATE.equals(convertAcl(acl))) { request.setAcl(AccessControlList.REST_CANNED_PRIVATE); } request.setBucketName(bucketName); request.setObjectKey(objectName); return request; } /** * 轉換字串許可權 * * @param acl * @return */ public static AccessControlList convertAcl(String acl) { AccessControlList aclObj; switch (acl) { case "private": aclObj = AccessControlList.REST_CANNED_PRIVATE; break; case "read_write": aclObj = AccessControlList.REST_CANNED_PUBLIC_READ_WRITE; break; default: aclObj = AccessControlList.REST_CANNED_PUBLIC_READ; } return aclObj; } }