update OSS模块 更新 阿里云 腾讯云 相关代码 重构部分代码结构
| | |
| | | endpoint: |
| | | logfile: |
| | | external-file: ./logs/sys-console.log |
| | | |
| | | --- # OSS 云存储(界面 <参数设置> 可切换) |
| | | cloud-storage: |
| | | # minio配置 |
| | | minio: |
| | | endpoint: http://localhost:9000 |
| | | accessKey: ruoyi |
| | | secretKey: ruoyi123 |
| | | bucketName: ruoyi |
| | | # 七牛云配置 |
| | | qiniu: |
| | | domain: http://XXX.XXXX.com |
| | | prefix: |
| | | accessKey: XXXXXXXXXXXXXXX |
| | | secretKey: XXXXXXXXXXXXXXX |
| | | bucketName: ruoyi |
| | | isHttps: false |
| | | # z0 华东 z1 华北 z2 华南 na0 北美 as0 东南亚 |
| | | # 不填为自动获取(性能低 易出问题) |
| | | region: z0 |
| | | # 阿里云配置 |
| | | aliyun: |
| | | endpoint: http://oss-cn-beijing.aliyuncs.com |
| | | prefix: |
| | | accessKeyId: XXXXXXXXXXXXXXX |
| | | accessKeySecret: XXXXXXXXXXXXXXX |
| | | bucketName: ruoyi |
| | | # 腾讯云配置 |
| | | qcloud: |
| | | endpoint: http://cos.ap-beijing.myqcloud.com |
| | | prefix: |
| | | secretId: XXXXXXXXXXXXXXX |
| | | secretKey: XXXXXXXXXXXXXXX |
| | | # 腾讯云bucket名规则 格式为 BucketName-APPID 此处填写的存储桶名称必须为此格式 |
| | | bucketName: ruoyi-1250000000 |
| | | isHttps: false |
| | | # 地域名参考官方文档 |
| | | # https://cloud.tencent.com/document/product/436/6224 |
| | | region: ap-beijing |
| | |
| | | endpoint: |
| | | logfile: |
| | | external-file: ./logs/sys-console.log |
| | | |
| | | --- # OSS 云存储(界面 <参数设置> 可切换) |
| | | cloud-storage: |
| | | # minio配置 |
| | | minio: |
| | | endpoint: http://172.30.0.54:9000 |
| | | accessKey: ruoyi |
| | | secretKey: ruoyi123 |
| | | bucketName: ruoyi |
| | | # 七牛云配置 |
| | | qiniu: |
| | | domain: http://XXX.XXXX.com |
| | | prefix: |
| | | accessKey: XXXXXXXXXXXXXXX |
| | | secretKey: XXXXXXXXXXXXXXX |
| | | bucketName: ruoyi |
| | | isHttps: false |
| | | # z0 华东 z1 华北 z2 华南 na0 北美 as0 东南亚 |
| | | # 不填为自动获取(性能低 易出问题) |
| | | region: z0 |
| | | # 阿里云配置 |
| | | aliyun: |
| | | endpoint: http://oss-cn-beijing.aliyuncs.com |
| | | prefix: |
| | | accessKeyId: XXXXXXXXXXXXXXX |
| | | accessKeySecret: XXXXXXXXXXXXXXX |
| | | bucketName: ruoyi |
| | | # 腾讯云配置 |
| | | qcloud: |
| | | endpoint: http://cos.ap-beijing.myqcloud.com |
| | | prefix: |
| | | secretId: XXXXXXXXXXXXXXX |
| | | secretKey: XXXXXXXXXXXXXXX |
| | | # 腾讯云bucket名规则 格式为 BucketName-APPID 此处填写的存储桶名称必须为此格式 |
| | | bucketName: ruoyi-1250000000 |
| | | isHttps: false |
| | | # 地域名参考官方文档 |
| | | # https://cloud.tencent.com/document/product/436/6224 |
| | | region: ap-beijing |
| | |
| | | |
| | | import com.ruoyi.oss.service.impl.AliyunCloudStorageServiceImpl; |
| | | import com.ruoyi.oss.service.impl.MinioCloudStorageServiceImpl; |
| | | import com.ruoyi.oss.service.impl.QcloudCloudStorageServiceImpl; |
| | | import com.ruoyi.oss.service.impl.QiniuCloudStorageServiceImpl; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | |
| | | /** |
| | | * 腾讯云 |
| | | */ |
| | | QCLOUD("qcloud", QiniuCloudStorageServiceImpl.class), |
| | | QCLOUD("qcloud", QcloudCloudStorageServiceImpl.class), |
| | | |
| | | /** |
| | | * minio |
| | |
| | | /** |
| | | * 腾讯云绑定的域名 |
| | | */ |
| | | private String domain; |
| | | private String endpoint; |
| | | |
| | | /** |
| | | * 腾讯云路径前缀 |
| | | */ |
| | | private String prefix; |
| | | |
| | | /** |
| | | * 腾讯云appId |
| | | */ |
| | | private String appId; |
| | | |
| | | /** |
| | | * 腾讯云SecretId |
| | |
| | | * 腾讯云BucketName |
| | | */ |
| | | private String bucketName; |
| | | |
| | | /** |
| | | * 七牛是否使用https |
| | | */ |
| | | private Boolean isHttps; |
| | | |
| | | /** |
| | | * 腾讯云COS所属地区 |
| | |
| | | private String region; |
| | | |
| | | /** |
| | | * 七牛存储区域 |
| | | * 七牛是否使用https |
| | | */ |
| | | private Boolean isHttps; |
| | | |
| | |
| | | */ |
| | | public interface ICloudStorageService { |
| | | |
| | | void createBucket(); |
| | | |
| | | /** |
| | | * 获取服务商类型 |
| | | */ |
| | |
| | | * @return 返回http地址 |
| | | */ |
| | | UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType); |
| | | |
| | | String getEndpointLink(); |
| | | } |
| | |
| | | public abstract class AbstractCloudStorageService implements ICloudStorageService, InitializingBean { |
| | | |
| | | @Override |
| | | public abstract void createBucket(); |
| | | |
| | | @Override |
| | | public abstract String getServiceType(); |
| | | |
| | | @Override |
| | |
| | | |
| | | @Override |
| | | public abstract void afterPropertiesSet() throws Exception; |
| | | |
| | | @Override |
| | | public abstract String getEndpointLink(); |
| | | } |
| | |
| | | package com.ruoyi.oss.service.impl; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.aliyun.oss.ClientConfiguration; |
| | | import com.aliyun.oss.OSSClient; |
| | | import com.aliyun.oss.common.auth.DefaultCredentialProvider; |
| | | import com.aliyun.oss.model.CannedAccessControlList; |
| | | import com.aliyun.oss.model.CreateBucketRequest; |
| | | import com.aliyun.oss.model.ObjectMetadata; |
| | | import com.aliyun.oss.model.PutObjectRequest; |
| | | import com.ruoyi.oss.entity.UploadResult; |
| | | import com.ruoyi.oss.enumd.CloudServiceEnumd; |
| | | import com.ruoyi.oss.exception.OssException; |
| | |
| | | this.properties.getAccessKeyId(), |
| | | this.properties.getAccessKeySecret()); |
| | | client = new OSSClient(this.properties.getEndpoint(), credentialProvider, configuration); |
| | | createBucket(); |
| | | } catch (Exception e) { |
| | | throw new IllegalArgumentException("阿里云存储配置错误! 请检查系统配置!"); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void createBucket() { |
| | | try { |
| | | String bucketName = properties.getBucketName(); |
| | | if (client.doesBucketExist(bucketName)) { |
| | | return; |
| | | } |
| | | CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName); |
| | | createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead); |
| | | client.createBucket(createBucketRequest); |
| | | } catch (Exception e) { |
| | | throw new OssException("创建Bucket失败, 请核对阿里云配置信息"); |
| | | } |
| | | } |
| | | |
| | |
| | | @Override |
| | | public UploadResult upload(InputStream inputStream, String path, String contentType) { |
| | | try { |
| | | client.putObject(this.properties.getBucketName(), path, inputStream); |
| | | ObjectMetadata metadata = new ObjectMetadata(); |
| | | metadata.setContentType(contentType); |
| | | client.putObject(new PutObjectRequest(properties.getBucketName(), path, inputStream, metadata)); |
| | | } catch (Exception e) { |
| | | throw new OssException("上传文件失败,请检查配置信息"); |
| | | throw new OssException("上传文件失败,请检查阿里云配置信息"); |
| | | } |
| | | return new UploadResult().setUrl(properties.getEndpoint() + "/" + path).setFilename(path); |
| | | return new UploadResult().setUrl(getEndpointLink() + "/" + path).setFilename(path); |
| | | } |
| | | |
| | | @Override |
| | | public void delete(String path) { |
| | | path = path.replace(this.properties.getEndpoint() + "/", ""); |
| | | path = path.replace(getEndpointLink() + "/", ""); |
| | | try { |
| | | client.deleteObject(this.properties.getBucketName(), path); |
| | | client.deleteObject(properties.getBucketName(), path); |
| | | } catch (Exception e) { |
| | | throw new OssException("上传文件失败,请检查配置信息"); |
| | | throw new OssException("上传文件失败,请检查阿里云配置信息"); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) { |
| | | return upload(data, getPath(this.properties.getPrefix(), suffix), contentType); |
| | | return upload(data, getPath(properties.getPrefix(), suffix), contentType); |
| | | } |
| | | |
| | | @Override |
| | | public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) { |
| | | return upload(inputStream, getPath(this.properties.getPrefix(), suffix), contentType); |
| | | return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType); |
| | | } |
| | | |
| | | @Override |
| | | public void afterPropertiesSet() throws Exception { |
| | | OssFactory.register(getServiceType(),this); |
| | | OssFactory.register(getServiceType(), this); |
| | | } |
| | | |
| | | @Override |
| | | public String getEndpointLink() { |
| | | String endpoint = properties.getEndpoint(); |
| | | StringBuilder sb = new StringBuilder(endpoint); |
| | | if (StrUtil.containsAnyIgnoreCase(endpoint, "http://")) { |
| | | sb.insert(7, properties.getBucketName() + "."); |
| | | } else if (StrUtil.containsAnyIgnoreCase(endpoint, "https://")) { |
| | | sb.insert(8, properties.getBucketName() + "."); |
| | | } else { |
| | | throw new OssException("Endpoint配置错误"); |
| | | } |
| | | return sb.toString(); |
| | | } |
| | | } |
| | |
| | | .endpoint(this.properties.getEndpoint()) |
| | | .credentials(this.properties.getAccessKey(), this.properties.getSecretKey()) |
| | | .build(); |
| | | String bucketName = this.properties.getBucketName(); |
| | | boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build()); |
| | | // 不存在就创建桶 |
| | | if (!exists) { |
| | | minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build()); |
| | | minioClient.setBucketPolicy(SetBucketPolicyArgs.builder() |
| | | .bucket(bucketName) |
| | | .config(getPolicy(bucketName, PolicyType.READ)) |
| | | .build()); |
| | | } |
| | | createBucket(); |
| | | } catch (Exception e) { |
| | | throw new IllegalArgumentException("Minio存储配置错误! 请检查系统配置!"); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void createBucket() { |
| | | try { |
| | | String bucketName = properties.getBucketName(); |
| | | boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build()); |
| | | if (exists) { |
| | | return; |
| | | } |
| | | // 不存在就创建桶 |
| | | minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build()); |
| | | minioClient.setBucketPolicy(SetBucketPolicyArgs.builder() |
| | | .bucket(bucketName) |
| | | .config(getPolicy(bucketName, PolicyType.READ)) |
| | | .build()); |
| | | } catch (Exception e) { |
| | | throw new OssException("创建Bucket失败, 请核对Minio配置信息"); |
| | | } |
| | | } |
| | | |
| | |
| | | } catch (Exception e) { |
| | | throw new OssException("上传文件失败,请核对Minio配置信息"); |
| | | } |
| | | return new UploadResult().setUrl(getBaseUrl() + path).setFilename(path); |
| | | return new UploadResult().setUrl(getEndpointLink() + "/" + path).setFilename(path); |
| | | } |
| | | |
| | | @Override |
| | | public void delete(String path) { |
| | | path = path.replace(getBaseUrl(), ""); |
| | | path = path.replace(getEndpointLink() + "/", ""); |
| | | try { |
| | | minioClient.removeObject(RemoveObjectArgs.builder() |
| | | .bucket(properties.getBucketName()) |
| | |
| | | OssFactory.register(getServiceType(), this); |
| | | } |
| | | |
| | | private String getBaseUrl() { |
| | | return properties.getEndpoint() + "/" + properties.getBucketName() + "/"; |
| | | @Override |
| | | public String getEndpointLink() { |
| | | return properties.getEndpoint() + "/" + properties.getBucketName(); |
| | | } |
| | | |
| | | private String getPolicy(String bucketName, PolicyType policyType) { |
| | |
| | | package com.ruoyi.oss.service.impl; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.qcloud.cos.COSClient; |
| | | import com.qcloud.cos.ClientConfig; |
| | | import com.qcloud.cos.auth.BasicCOSCredentials; |
| | | import com.qcloud.cos.auth.COSCredentials; |
| | | import com.qcloud.cos.http.HttpProtocol; |
| | | import com.qcloud.cos.model.*; |
| | | import com.qcloud.cos.region.Region; |
| | | import com.ruoyi.oss.entity.UploadResult; |
| | | import com.ruoyi.oss.enumd.CloudServiceEnumd; |
| | | import com.ruoyi.oss.exception.OssException; |
| | | import com.ruoyi.oss.factory.OssFactory; |
| | | import com.ruoyi.oss.properties.CloudStorageProperties; |
| | | import com.ruoyi.oss.properties.CloudStorageProperties.QcloudProperties; |
| | |
| | | import org.springframework.context.annotation.Lazy; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.io.ByteArrayInputStream; |
| | | import java.io.InputStream; |
| | | |
| | | /** |
| | |
| | | ClientConfig clientConfig = new ClientConfig(); |
| | | // 设置bucket所在的区域,华南:gz 华北:tj 华东:sh |
| | | clientConfig.setRegion(new Region(this.properties.getRegion())); |
| | | if (this.properties.getIsHttps()) { |
| | | clientConfig.setHttpProtocol(HttpProtocol.https); |
| | | } else { |
| | | clientConfig.setHttpProtocol(HttpProtocol.http); |
| | | } |
| | | client = new COSClient(credentials, clientConfig); |
| | | createBucket(); |
| | | } catch (Exception e) { |
| | | throw new IllegalArgumentException("腾讯云存储配置错误! 请检查系统配置!"); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void createBucket() { |
| | | try { |
| | | String bucketName = properties.getBucketName(); |
| | | if (client.doesBucketExist(bucketName)) { |
| | | return; |
| | | } |
| | | CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName); |
| | | createBucketRequest.setCannedAcl(CannedAccessControlList.PublicRead); |
| | | client.createBucket(createBucketRequest); |
| | | } catch (Exception e) { |
| | | throw new OssException("创建Bucket失败, 请核对腾讯云配置信息"); |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | @Override |
| | | public UploadResult upload(byte[] data, String path, String contentType) { |
| | | // 腾讯云必需要以"/"开头 |
| | | if (!path.startsWith("/")) { |
| | | path = "/" + path; |
| | | return upload(new ByteArrayInputStream(data), path, contentType); |
| | | } |
| | | |
| | | @Override |
| | | public UploadResult upload(InputStream inputStream, String path, String contentType) { |
| | | try { |
| | | ObjectMetadata metadata = new ObjectMetadata(); |
| | | metadata.setContentType(contentType); |
| | | client.putObject(new PutObjectRequest(properties.getBucketName(), path, inputStream, metadata)); |
| | | } catch (Exception e) { |
| | | throw new OssException("上传文件失败,请检查腾讯云配置信息"); |
| | | } |
| | | // 上传到腾讯云 |
| | | // UploadFileRequest request = new UploadFileRequest(config.getQcloudBucketName(), path, data); |
| | | // String response = client.uploadFile(request); |
| | | // Map<String, Object> jsonObject = JsonUtils.parseMap(response); |
| | | // if (Convert.toInt(jsonObject.get("code")) != 0) { |
| | | // throw new OssException("文件上传失败," + Convert.toStr(jsonObject.get("message"))); |
| | | // } |
| | | return new UploadResult().setUrl(properties.getDomain() + "/" + path).setFilename(path); |
| | | return new UploadResult().setUrl(getEndpointLink() + "/" + path).setFilename(path); |
| | | } |
| | | |
| | | @Override |
| | | public void delete(String path) { |
| | | // path = path.replace(config.getDomain(),""); |
| | | // DelFileRequest request = new DelFileRequest(config.getBucketName(), path); |
| | | // String response = client.delFile(request); |
| | | // Map<String, Object> jsonObject = JsonUtils.parseMap(response); |
| | | // if (Convert.toInt(jsonObject.get("code")) != 0) { |
| | | // throw new OssException("文件删除失败," + Convert.toStr(jsonObject.get("message"))); |
| | | // } |
| | | path = path.replace(getEndpointLink() + "/", ""); |
| | | try { |
| | | client.deleteObject(new DeleteObjectRequest(properties.getBucketName(), path)); |
| | | } catch (Exception e) { |
| | | throw new OssException("上传文件失败,请检腾讯云查配置信息"); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) { |
| | | return upload(data, getPath(this.properties.getPrefix(), suffix), contentType); |
| | | return upload(data, getPath(properties.getPrefix(), suffix), contentType); |
| | | } |
| | | |
| | | @Override |
| | | public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) { |
| | | return upload(inputStream, getPath(this.properties.getPrefix(), suffix), contentType); |
| | | return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType); |
| | | } |
| | | |
| | | @Override |
| | | public void afterPropertiesSet() throws Exception { |
| | | OssFactory.register(getServiceType(),this); |
| | | } |
| | | |
| | | @Override |
| | | public String getEndpointLink() { |
| | | String endpoint = properties.getEndpoint(); |
| | | StringBuilder sb = new StringBuilder(endpoint); |
| | | if (StrUtil.containsAnyIgnoreCase(endpoint, "http://")) { |
| | | sb.insert(7, properties.getBucketName() + "."); |
| | | } else if (StrUtil.containsAnyIgnoreCase(endpoint, "https://")) { |
| | | sb.insert(8, properties.getBucketName() + "."); |
| | | } else { |
| | | throw new OssException("Endpoint配置错误"); |
| | | } |
| | | return sb.toString(); |
| | | } |
| | | } |
| | |
| | | Auth auth = Auth.create( |
| | | this.properties.getAccessKey(), |
| | | this.properties.getSecretKey()); |
| | | token = auth.uploadToken(this.properties.getBucketName()); |
| | | String bucketName = this.properties.getBucketName(); |
| | | token = auth.uploadToken(bucketName); |
| | | bucketManager = new BucketManager(auth, config); |
| | | |
| | | if (!ArrayUtil.contains(bucketManager.buckets(), this.properties.getBucketName())) { |
| | | bucketManager.createBucket(this.properties.getBucketName(), this.properties.getRegion()); |
| | | if (!ArrayUtil.contains(bucketManager.buckets(), bucketName)) { |
| | | bucketManager.createBucket(bucketName, this.properties.getRegion()); |
| | | } |
| | | } catch (Exception e) { |
| | | throw new IllegalArgumentException("七牛云存储配置错误! 请检查系统配置!"); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void createBucket() { |
| | | try { |
| | | String bucketName = properties.getBucketName(); |
| | | if (ArrayUtil.contains(bucketManager.buckets(), bucketName)) { |
| | | return; |
| | | } |
| | | bucketManager.createBucket(bucketName, properties.getRegion()); |
| | | } catch (Exception e) { |
| | | throw new OssException("创建Bucket失败, 请核对七牛云配置信息"); |
| | | } |
| | | } |
| | | |
| | |
| | | @Override |
| | | public UploadResult upload(byte[] data, String path, String contentType) { |
| | | try { |
| | | Response res = uploadManager.put(data, path, token); |
| | | Response res = uploadManager.put(data, path, token, null, contentType, false); |
| | | if (!res.isOK()) { |
| | | throw new RuntimeException("上传七牛出错:" + res.toString()); |
| | | } |
| | | } catch (Exception e) { |
| | | throw new OssException("上传文件失败,请核对七牛配置信息"); |
| | | } |
| | | return new UploadResult().setUrl(properties.getDomain() + "/" + path).setFilename(path); |
| | | return new UploadResult().setUrl(getEndpointLink() + "/" + path).setFilename(path); |
| | | } |
| | | |
| | | @Override |
| | | public void delete(String path) { |
| | | try { |
| | | path = path.replace(this.properties.getDomain() + "/", ""); |
| | | Response res = bucketManager.delete(this.properties.getBucketName(), path); |
| | | path = path.replace(getEndpointLink() + "/", ""); |
| | | Response res = bucketManager.delete(properties.getBucketName(), path); |
| | | if (!res.isOK()) { |
| | | throw new RuntimeException("删除七牛文件出错:" + res.toString()); |
| | | } |
| | |
| | | |
| | | @Override |
| | | public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) { |
| | | return upload(data, getPath(this.properties.getPrefix(), suffix), contentType); |
| | | return upload(data, getPath(properties.getPrefix(), suffix), contentType); |
| | | } |
| | | |
| | | @Override |
| | | public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) { |
| | | return upload(inputStream, getPath(this.properties.getPrefix(), suffix), contentType); |
| | | return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType); |
| | | } |
| | | |
| | | @Override |
| | |
| | | OssFactory.register(getServiceType(),this); |
| | | } |
| | | |
| | | @Override |
| | | public String getEndpointLink() { |
| | | return properties.getDomain(); |
| | | } |
| | | |
| | | private Region getRegion(String region) { |
| | | switch (region) { |
| | | case "z0": |