整合华为云OBS上传工具类
项目启动的要加上配置文件的扫描路径
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; } }