From ae9c36cc7aecd5217fc877fbc44aab2f4c79e6d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90li?= <15040126243@163.com> Date: Tue, 10 May 2022 14:55:18 +0800 Subject: [PATCH] =?UTF-8?q?update=20=E8=A1=A5=E5=85=A8=E9=81=97=E6=BC=8F?= =?UTF-8?q?=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/ruoyi/common/oss/core/OssClient.java | 189 ++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/core/OssClient.java diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/core/OssClient.java b/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/core/OssClient.java new file mode 100644 index 00000000..809bc0d4 --- /dev/null +++ b/ruoyi-common/ruoyi-common-oss/src/main/java/com/ruoyi/common/oss/core/OssClient.java @@ -0,0 +1,189 @@ +package com.ruoyi.common.oss.core; + +import cn.hutool.core.util.IdUtil; +import com.amazonaws.ClientConfiguration; +import com.amazonaws.Protocol; +import com.amazonaws.auth.AWSCredentials; +import com.amazonaws.auth.AWSCredentialsProvider; +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.client.builder.AwsClientBuilder; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3Client; +import com.amazonaws.services.s3.model.CannedAccessControlList; +import com.amazonaws.services.s3.model.CreateBucketRequest; +import com.amazonaws.services.s3.model.ObjectMetadata; +import com.amazonaws.services.s3.model.PutObjectRequest; +import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.oss.constant.OssConstant; +import com.ruoyi.common.oss.entity.UploadResult; +import com.ruoyi.common.oss.enumd.PolicyType; +import com.ruoyi.common.oss.exception.OssException; +import com.ruoyi.common.oss.properties.OssProperties; + + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +/** + * S3 存储协议 所有兼容S3协议的云厂商均支持 + * 阿里云 腾讯云 七牛云 minio + * + * @author Lion Li + */ +public class OssClient { + + private final String configKey; + + private final OssProperties properties; + + private final AmazonS3 client; + + public OssClient(String configKey, OssProperties ossProperties) { + this.configKey = configKey; + this.properties = ossProperties; + try { + AwsClientBuilder.EndpointConfiguration endpointConfig = + new AwsClientBuilder.EndpointConfiguration(properties.getEndpoint(), properties.getRegion()); + + AWSCredentials credentials = new BasicAWSCredentials(properties.getAccessKey(), properties.getSecretKey()); + AWSCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvider(credentials); + ClientConfiguration clientConfig = new ClientConfiguration(); + if (OssConstant.IS_HTTPS.equals(properties.getIsHttps())) { + clientConfig.setProtocol(Protocol.HTTPS); + } else { + clientConfig.setProtocol(Protocol.HTTP); + } + this.client = AmazonS3Client.builder() + .withEndpointConfiguration(endpointConfig) + .withClientConfiguration(clientConfig) + .withCredentials(credentialsProvider) + .disableChunkedEncoding() + .build(); + + createBucket(); + } catch (Exception e) { + if (e instanceof OssException) { + throw e; + } + throw new OssException("配置错误! 请检查系统配置:[" + e.getMessage() + "]"); + } + } + + public void createBucket() { + try { + String bucketName = properties.getBucketName(); + if (client.doesBucketExistV2(bucketName)) { + return; + } + CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName); + createBucketRequest.setCannedAcl(CannedAccessControlList.PublicRead); + client.createBucket(createBucketRequest); + client.setBucketPolicy(bucketName, getPolicy(bucketName, PolicyType.READ)); + } catch (Exception e) { + throw new OssException("创建Bucket失败, 请核对配置信息:[" + e.getMessage() + "]"); + } + } + + public UploadResult upload(byte[] data, String path, String contentType) { + return upload(new ByteArrayInputStream(data), path, contentType); + } + + public UploadResult upload(InputStream inputStream, String path, String contentType) { + try { + ObjectMetadata metadata = new ObjectMetadata(); + metadata.setContentType(contentType); + metadata.setContentLength(inputStream.available()); + client.putObject(new PutObjectRequest(properties.getBucketName(), path, inputStream, metadata)); + } catch (Exception e) { + throw new OssException("上传文件失败,请检查配置信息:[" + e.getMessage() + "]"); + } + return UploadResult.builder().url(getUrl() + "/" + path).filename(path).build(); + } + + public void delete(String path) { + path = path.replace(getUrl() + "/", ""); + try { + client.deleteObject(properties.getBucketName(), path); + } catch (Exception e) { + throw new OssException("上传文件失败,请检查配置信息:[" + e.getMessage() + "]"); + } + } + + public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) { + return upload(data, getPath(properties.getPrefix(), suffix), contentType); + } + + public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) { + return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType); + } + + public String getUrl() { + String domain = properties.getDomain(); + if (StringUtils.isNotBlank(domain)) { + return domain; + } + String endpoint = properties.getEndpoint(); + String header = OssConstant.IS_HTTPS.equals(properties.getIsHttps()) ? "https://" : "http://"; + // 云服务商直接返回 + if (StringUtils.containsAny(endpoint, OssConstant.CLOUD_SERVICE)){ + return header + properties.getBucketName() + "." + endpoint; + } + // minio 单独处理 + return header + endpoint + "/" + properties.getBucketName(); + } + + public String getPath(String prefix, String suffix) { + // 生成uuid + String uuid = IdUtil.fastSimpleUUID(); + // 文件路径 + String path = DateUtils.datePath() + "/" + uuid; + if (StringUtils.isNotBlank(prefix)) { + path = prefix + "/" + path; + } + return path + suffix; + } + + + public String getConfigKey() { + return configKey; + } + + private static String getPolicy(String bucketName, PolicyType policyType) { + StringBuilder builder = new StringBuilder(); + builder.append("{\n\"Statement\": [\n{\n\"Action\": [\n"); + if (policyType == PolicyType.WRITE) { + builder.append("\"s3:GetBucketLocation\",\n\"s3:ListBucketMultipartUploads\"\n"); + } else if (policyType == PolicyType.READ_WRITE) { + builder.append("\"s3:GetBucketLocation\",\n\"s3:ListBucket\",\n\"s3:ListBucketMultipartUploads\"\n"); + } else { + builder.append("\"s3:GetBucketLocation\"\n"); + } + builder.append("],\n\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::"); + builder.append(bucketName); + builder.append("\"\n},\n"); + if (policyType == PolicyType.READ) { + builder.append("{\n\"Action\": [\n\"s3:ListBucket\"\n],\n\"Effect\": \"Deny\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::"); + builder.append(bucketName); + builder.append("\"\n},\n"); + } + builder.append("{\n\"Action\": "); + switch (policyType) { + case WRITE: + builder.append("[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n"); + break; + case READ_WRITE: + builder.append("[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:GetObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n"); + break; + default: + builder.append("\"s3:GetObject\",\n"); + break; + } + builder.append("\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::"); + builder.append(bucketName); + builder.append("/*\"\n}\n],\n\"Version\": \"2012-10-17\"\n}\n"); + return builder.toString(); + } + +}