1、增加qiniu云存储; 2:重构config; 3: 重新命名
This commit is contained in:
parent
046c27d71c
commit
fb028d7091
|
|
@ -119,6 +119,14 @@
|
||||||
<version>1.11.415</version>
|
<version>1.11.415</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!--ceph upload end -->
|
<!--ceph upload end -->
|
||||||
|
|
||||||
|
<!--七牛云文件存储 start -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.qiniu</groupId>
|
||||||
|
<artifactId>qiniu-java-sdk</artifactId>
|
||||||
|
<version>[7.7.0, 7.7.99]</version>
|
||||||
|
</dependency>
|
||||||
|
<!--七牛云文件存储 end -->
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,31 @@
|
||||||
package com.ruoyi.file;
|
package com.ruoyi.file;
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
import com.ruoyi.common.swagger.annotation.EnableCustomSwagger2;
|
import com.ruoyi.common.swagger.annotation.EnableCustomSwagger2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件服务
|
* 文件服务
|
||||||
*
|
*
|
||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
*/
|
*/
|
||||||
@EnableCustomSwagger2
|
@EnableCustomSwagger2
|
||||||
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
|
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
|
||||||
public class RuoYFileApplication
|
public class RuoYiFileApplication
|
||||||
{
|
{
|
||||||
public static void main(String[] args)
|
public static void main(String[] args)
|
||||||
{
|
{
|
||||||
SpringApplication.run(RuoYFileApplication.class, args);
|
SpringApplication.run(RuoYiFileApplication.class, args);
|
||||||
System.out.println("(♥◠‿◠)ノ゙ 文件服务模块启动成功 ლ(´ڡ`ლ)゙ \n" +
|
System.out.println("(♥◠‿◠)ノ゙ 文件服务模块启动成功 ლ(´ڡ`ლ)゙ \n" +
|
||||||
" .-------. ____ __ \n" +
|
" .-------. ____ __ \n" +
|
||||||
" | _ _ \\ \\ \\ / / \n" +
|
" | _ _ \\ \\ \\ / / \n" +
|
||||||
" | ( ' ) | \\ _. / ' \n" +
|
" | ( ' ) | \\ _. / ' \n" +
|
||||||
" |(_ o _) / _( )_ .' \n" +
|
" |(_ o _) / _( )_ .' \n" +
|
||||||
" | (_,_).' __ ___(_ o _)' \n" +
|
" | (_,_).' __ ___(_ o _)' \n" +
|
||||||
" | |\\ \\ | || |(_,_)' \n" +
|
" | |\\ \\ | || |(_,_)' \n" +
|
||||||
" | | \\ `' /| `-' / \n" +
|
" | | \\ `' /| `-' / \n" +
|
||||||
" | | \\ / \\ / \n" +
|
" | | \\ / \\ / \n" +
|
||||||
" ''-' `'-' `-..-' ");
|
" ''-' `'-' `-..-' ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.ruoyi.file.config;
|
package com.ruoyi.file.config;
|
||||||
|
|
||||||
|
import com.ruoyi.file.service.AliyunOssDsfServiceImpl;
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
@ -8,10 +9,12 @@ import org.springframework.context.annotation.Configuration;
|
||||||
* aliyun oss https://help.aliyun.com/learn/learningpath/oss.html ,需要购买
|
* aliyun oss https://help.aliyun.com/learn/learningpath/oss.html ,需要购买
|
||||||
*
|
*
|
||||||
* @author dazer
|
* @author dazer
|
||||||
|
*
|
||||||
|
* @see AliyunOssDsfServiceImpl
|
||||||
*/
|
*/
|
||||||
@RefreshScope
|
@RefreshScope
|
||||||
@Configuration
|
@Configuration
|
||||||
@ConfigurationProperties(prefix = "aliyun.oss")
|
@ConfigurationProperties(prefix = "aliyunoss")
|
||||||
public class AliyunOssConfig {
|
public class AliyunOssConfig {
|
||||||
/**
|
/**
|
||||||
* aliyun oss相关配置
|
* aliyun oss相关配置
|
||||||
|
|
@ -20,11 +23,26 @@ public class AliyunOssConfig {
|
||||||
* AccessKeySecret eg:ap8nmIvD1TctcCLsADS4JbkOoXOluW
|
* AccessKeySecret eg:ap8nmIvD1TctcCLsADS4JbkOoXOluW
|
||||||
* BucketName eg:yuebaoxiao
|
* BucketName eg:yuebaoxiao
|
||||||
* Endpoint eg:oss-cn-shenzhen.aliyuncs.com
|
* Endpoint eg:oss-cn-shenzhen.aliyuncs.com
|
||||||
|
*
|
||||||
|
* ak 获取地址:https://ak-console.aliyun.com/#/accesskey
|
||||||
|
*
|
||||||
|
* 具体项目里面必须替换掉
|
||||||
*/
|
*/
|
||||||
private String accessKeyId;
|
private String accessKeyId = "";
|
||||||
private String accessKeySecret;
|
private String accessKeySecret = "";
|
||||||
private String ossBucketName;
|
private String bucketName = "";
|
||||||
private String ossEndpoint;
|
private String endpoint = "";
|
||||||
|
/**
|
||||||
|
* hostHttps: 是否开启了https, 需要在控制台配置
|
||||||
|
* https://oss.console.aliyun.com/bucket/oss-cn-shanghai/hiber2019/domain
|
||||||
|
* <p>
|
||||||
|
* 上传地址和访问地址经常是不一样的
|
||||||
|
* 1、上传地址是内网;访问地址是外网;
|
||||||
|
* 2、上传地址是ip; 访问地址域名;
|
||||||
|
* 3、上传地址是http; 访问地址是https
|
||||||
|
* 4: eg: https://image.jl-media.cn
|
||||||
|
*/
|
||||||
|
private String domain = null;
|
||||||
|
|
||||||
public String getAccessKeyId() {
|
public String getAccessKeyId() {
|
||||||
return accessKeyId;
|
return accessKeyId;
|
||||||
|
|
@ -42,19 +60,27 @@ public class AliyunOssConfig {
|
||||||
this.accessKeySecret = accessKeySecret;
|
this.accessKeySecret = accessKeySecret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOssBucketName() {
|
public String getBucketName() {
|
||||||
return ossBucketName;
|
return bucketName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOssBucketName(String ossBucketName) {
|
public void setBucketName(String bucketName) {
|
||||||
this.ossBucketName = ossBucketName;
|
this.bucketName = bucketName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOssEndpoint() {
|
public String getEndpoint() {
|
||||||
return ossEndpoint;
|
return endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOssEndpoint(String ossEndpoint) {
|
public void setEndpoint(String endpoint) {
|
||||||
this.ossEndpoint = ossEndpoint;
|
this.endpoint = endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDomain() {
|
||||||
|
return domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDomain(String domain) {
|
||||||
|
this.domain = domain;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
package com.ruoyi.file.config;
|
||||||
|
|
||||||
|
import com.ruoyi.file.service.CephDfsServiceImpl;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see CephDfsServiceImpl
|
||||||
|
* @author dazer
|
||||||
|
*/
|
||||||
|
@RefreshScope
|
||||||
|
@Configuration
|
||||||
|
@ConfigurationProperties(
|
||||||
|
prefix = "ceph"
|
||||||
|
)
|
||||||
|
public class CephConfig {
|
||||||
|
/**
|
||||||
|
* s3 提供的 accessKey secretKey
|
||||||
|
* 示例:
|
||||||
|
* AccessKey: XPVF8TESA1X4SFU*****
|
||||||
|
* SecretKey: hBBEFpV3qsyI7HAdCBzA2ZdAhuANJFRIUz****
|
||||||
|
* BUCKET_NAME: 概念和阿里云 oss 一模一样
|
||||||
|
* endpoint: 127.0.0.1 or oss-cn-shenzhen.aliyuncs.com
|
||||||
|
*/
|
||||||
|
private String accessKey = "";
|
||||||
|
private String secretKey = "";
|
||||||
|
private String endpoint = "127.0.0.1";
|
||||||
|
private String bucketName = "";
|
||||||
|
/**
|
||||||
|
* 访问地址,访问地址经常和上传地址不一样;
|
||||||
|
* 1:上传地址是内网; 访问地址外网;
|
||||||
|
* 2:上传地址ip; 访问地址域名;
|
||||||
|
* 3-1:eg: https://dfwwbook.oss-cn-zhangjiakou.aliyuncs.com/upload/product/20210625165727777_dzdpl.jpg
|
||||||
|
* 3-2:eg: https://dfwwbook.dfww.com.cn/upload/product/20210625165727777_dzdpl.jpg
|
||||||
|
* 4: 示例:domain: https://dfwwbook.dfww.com.cn
|
||||||
|
* 最后带不带斜杠都可以
|
||||||
|
*/
|
||||||
|
private String domain = null;
|
||||||
|
|
||||||
|
public String getAccessKey() {
|
||||||
|
return accessKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccessKey(String accessKey) {
|
||||||
|
this.accessKey = accessKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSecretKey() {
|
||||||
|
return secretKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSecretKey(String secretKey) {
|
||||||
|
this.secretKey = secretKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEndpoint() {
|
||||||
|
return endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEndpoint(String endpoint) {
|
||||||
|
this.endpoint = endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBucketName() {
|
||||||
|
return bucketName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBucketName(String bucketName) {
|
||||||
|
this.bucketName = bucketName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDomain() {
|
||||||
|
return domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDomain(String domain) {
|
||||||
|
this.domain = domain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.ruoyi.file.config;
|
||||||
|
|
||||||
|
import com.github.tobato.fastdfs.FdfsClientConstants;
|
||||||
|
import com.github.tobato.fastdfs.domain.conn.PooledConnectionFactory;
|
||||||
|
import com.ruoyi.file.service.FastDfsServiceImpl;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阿里 fastdfs 配置
|
||||||
|
* @author dazer
|
||||||
|
* @see FastDfsServiceImpl
|
||||||
|
* FastDFS配置 其他参数见:{@link PooledConnectionFactory}
|
||||||
|
*/
|
||||||
|
@RefreshScope
|
||||||
|
@Configuration
|
||||||
|
@ConfigurationProperties(
|
||||||
|
prefix = FdfsClientConstants.ROOT_CONFIG_PREFIX
|
||||||
|
)
|
||||||
|
public class FastDfsConfig extends PooledConnectionFactory {
|
||||||
|
/**
|
||||||
|
* 域名或本机访问地址
|
||||||
|
* FastDFS配置 其他参数见:{@link PooledConnectionFactory}
|
||||||
|
* //@Value("${fdfs.domain}")
|
||||||
|
*/
|
||||||
|
public String domain;
|
||||||
|
|
||||||
|
public String getDomain() {
|
||||||
|
return domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDomain(String domain) {
|
||||||
|
this.domain = domain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,40 +1,73 @@
|
||||||
package com.ruoyi.file.config;
|
package com.ruoyi.file.config;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
/**
|
|
||||||
* 通用映射配置
|
/**
|
||||||
*
|
* 本地文件配置
|
||||||
* @author ruoyi
|
* 通用映射配置
|
||||||
*/
|
*
|
||||||
@RefreshScope
|
* @author ruoyi
|
||||||
@Configuration
|
*/
|
||||||
public class ResourcesConfig implements WebMvcConfigurer
|
@RefreshScope
|
||||||
{
|
@Configuration
|
||||||
/**
|
public class LocalConfig implements WebMvcConfigurer
|
||||||
* 上传文件存储在本地的根路径
|
{
|
||||||
* eg: D:/ruoyi/uploadPath
|
/**
|
||||||
*/
|
* 资源映射路径 前缀
|
||||||
@Value("${file.path}")
|
* eg: eg: /statics
|
||||||
private String localFilePath;
|
*/
|
||||||
|
@Value("${file.prefix}")
|
||||||
/**
|
private String localFilePrefix;
|
||||||
* 资源映射路径 前缀
|
|
||||||
* eg: /statics
|
/**
|
||||||
*/
|
* 域名或本机访问地址
|
||||||
@Value("${file.prefix}")
|
* eg: http://127.0.0.1:9300
|
||||||
public String localFilePrefix;
|
*/
|
||||||
|
@Value("${file.domain}")
|
||||||
@Override
|
private String domain;
|
||||||
public void addResourceHandlers(ResourceHandlerRegistry registry)
|
|
||||||
{
|
/**
|
||||||
/** 本地文件上传路径 */
|
* 上传文件存储在本地的根路径
|
||||||
registry.addResourceHandler(localFilePrefix + "/**")
|
* eg: D:/ruoyi/uploadPath
|
||||||
.addResourceLocations("file:" + localFilePath + File.separator);
|
*/
|
||||||
}
|
@Value("${file.path}")
|
||||||
|
private String localFilePath;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addResourceHandlers(ResourceHandlerRegistry registry)
|
||||||
|
{
|
||||||
|
/** 本地文件上传路径 */
|
||||||
|
registry.addResourceHandler(localFilePrefix + "/**")
|
||||||
|
.addResourceLocations("file:" + localFilePath + File.separator);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLocalFilePrefix() {
|
||||||
|
return localFilePrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocalFilePrefix(String localFilePrefix) {
|
||||||
|
this.localFilePrefix = localFilePrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDomain() {
|
||||||
|
return domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDomain(String domain) {
|
||||||
|
this.domain = domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLocalFilePath() {
|
||||||
|
return localFilePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocalFilePath(String localFilePath) {
|
||||||
|
this.localFilePath = localFilePath;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
package com.ruoyi.file.config;
|
||||||
|
|
||||||
|
import com.qiniu.storage.Region;
|
||||||
|
import com.qiniu.storage.UploadManager;
|
||||||
|
import com.ruoyi.file.service.QiniuDfsServiceImpl;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 七牛 文件存储产品叫做:kodo
|
||||||
|
* 对象存储:https://developer.qiniu.com/kodo/1239/java
|
||||||
|
* @author dazer
|
||||||
|
* @see UploadManager 上传核心类
|
||||||
|
* @see Region 区域 or endpoint 【可选】
|
||||||
|
* @see com.qiniu.storage.Configuration 配置类,可以配置 上传区域; 【可选】
|
||||||
|
* @see QiniuDfsServiceImpl 实现
|
||||||
|
*/
|
||||||
|
@RefreshScope
|
||||||
|
@Configuration
|
||||||
|
@ConfigurationProperties(prefix = "qiniu")
|
||||||
|
public class QiniuKodoConfig {
|
||||||
|
/**
|
||||||
|
* AccessKey 简称ak
|
||||||
|
* 申请地址=>登录七牛云:https://portal.qiniu.com/user/key
|
||||||
|
* ak 形如:pRYrSe_EW4sJHsQ6JyuiRYShA2JCLKtMhT-N4TQD
|
||||||
|
* ===============================================
|
||||||
|
* SecretKey 简称 sk
|
||||||
|
* 形如:CwTEh1kSLBdxBhIWfFz6h1GgDSokx97CYEV0cC1O
|
||||||
|
* ===============================================
|
||||||
|
* bucketName 获取地址:https://portal.qiniu.com/kodo/bucket
|
||||||
|
* ===============================================
|
||||||
|
* domain: 域名,一般都另外单独设置有一个访问的域名
|
||||||
|
* ===============================================
|
||||||
|
* Region or endpoint: 七牛云会自动选择合适的
|
||||||
|
*/
|
||||||
|
private String accessKey;
|
||||||
|
private String secretKey;
|
||||||
|
private String bucketName;
|
||||||
|
private String domain;
|
||||||
|
|
||||||
|
public String getAccessKey() {
|
||||||
|
return accessKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccessKey(String accessKey) {
|
||||||
|
this.accessKey = accessKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSecretKey() {
|
||||||
|
return secretKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSecretKey(String secretKey) {
|
||||||
|
this.secretKey = secretKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBucketName() {
|
||||||
|
return bucketName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBucketName(String bucketName) {
|
||||||
|
this.bucketName = bucketName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDomain() {
|
||||||
|
return domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDomain(String domain) {
|
||||||
|
this.domain = domain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.ruoyi.file.controller;
|
package com.ruoyi.file.controller;
|
||||||
|
|
||||||
|
import com.ruoyi.file.service.IDfsService;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
@ -8,7 +9,6 @@ import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import com.ruoyi.common.core.domain.R;
|
import com.ruoyi.common.core.domain.R;
|
||||||
import com.ruoyi.common.core.utils.file.FileUtils;
|
import com.ruoyi.common.core.utils.file.FileUtils;
|
||||||
import com.ruoyi.file.service.ISysFileService;
|
|
||||||
import com.ruoyi.system.api.domain.SysFile;
|
import com.ruoyi.system.api.domain.SysFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -22,7 +22,7 @@ public class SysFileController
|
||||||
private static final Logger log = LoggerFactory.getLogger(SysFileController.class);
|
private static final Logger log = LoggerFactory.getLogger(SysFileController.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISysFileService sysFileService;
|
private IDfsService sysFileService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件上传请求
|
* 文件上传请求
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
@ -43,45 +42,10 @@ import java.util.concurrent.TimeUnit;
|
||||||
* //@see AliyunMsgUtil
|
* //@see AliyunMsgUtil
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class AliyunOssFileServiceImpl implements ISysFileService {
|
public class AliyunOssDsfServiceImpl implements IDfsService {
|
||||||
private static final Logger log = LoggerFactory.getLogger(AliyunOssFileServiceImpl.class);
|
private static final Logger log = LoggerFactory.getLogger(AliyunOssDsfServiceImpl.class);
|
||||||
@Autowired
|
@Autowired
|
||||||
private AliyunOssConfig aliyunOssConfig;
|
private AliyunOssConfig aliyunOssConfig;
|
||||||
/**
|
|
||||||
* 这些阿里云访问id
|
|
||||||
*/
|
|
||||||
private String ACCESS_KEY_ID;
|
|
||||||
private String ACCESS_KEY_SECRET;
|
|
||||||
private String BUCKET_NAME;
|
|
||||||
/**
|
|
||||||
* https://oss.console.aliyun.com/
|
|
||||||
* 这些阿里云 oss 参数都需要替换
|
|
||||||
* <p>
|
|
||||||
* 如果是内网的话,访问速度肯定更快,内网不限制速度。
|
|
||||||
*/
|
|
||||||
private String ENDPOINT = "oss-cn-shenzhen.aliyuncs.com";
|
|
||||||
private String ENDPOINT_INTERNAL = ENDPOINT.replace(".aliyuncs.com", "-internal.aliyuncs.com");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 域名绑定
|
|
||||||
* USER_DOMAIN_NAME: 域名名称, oss 访问路径绑定的用户自定义域名; 如果没有,就设置为null
|
|
||||||
* hostHttps: 是否开启了https, 需要在控制台配置
|
|
||||||
* https://oss.console.aliyun.com/bucket/oss-cn-shanghai/hiber2019/domain
|
|
||||||
* <p>
|
|
||||||
* private static final String USER_DOMAIN_NAME = "image.jl-media.cn";
|
|
||||||
*/
|
|
||||||
private static final String USER_DOMAIN_NAME = null;
|
|
||||||
private static final boolean HOST_HTTPS = true;
|
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
public void init() {
|
|
||||||
ACCESS_KEY_ID = aliyunOssConfig.getAccessKeyId();
|
|
||||||
ACCESS_KEY_SECRET = aliyunOssConfig.getAccessKeySecret();
|
|
||||||
BUCKET_NAME = aliyunOssConfig.getOssBucketName();
|
|
||||||
ENDPOINT = aliyunOssConfig.getOssEndpoint();
|
|
||||||
ENDPOINT_INTERNAL = ENDPOINT.replace(".aliyuncs.com", "-internal.aliyuncs.com");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* demo 地址 https://help.aliyun.com/learn/learningpath/oss.html
|
* demo 地址 https://help.aliyun.com/learn/learningpath/oss.html
|
||||||
* <p>
|
* <p>
|
||||||
|
|
@ -107,26 +71,31 @@ public class AliyunOssFileServiceImpl implements ISysFileService {
|
||||||
requestKey = SpringUtil.getActiveProfile() + "/" + requestKey;
|
requestKey = SpringUtil.getActiveProfile() + "/" + requestKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://oss.console.aliyun.com/
|
||||||
|
* 这些阿里云 oss 参数都需要替换
|
||||||
|
* <p>
|
||||||
|
* 如果是内网的话,访问速度肯定更快,内网不限制速度。
|
||||||
|
*/
|
||||||
|
String endpoint = aliyunOssConfig.getEndpoint();
|
||||||
|
String endpointInternal = endpoint.replace(".aliyuncs.com", "-internal.aliyuncs.com");
|
||||||
|
|
||||||
long mb5 = 5 * 1024 * 1024L;
|
long mb5 = 5 * 1024 * 1024L;
|
||||||
if (file.getSize() > mb5) {
|
if (file.getSize() > mb5) {
|
||||||
//大于5mb,我们就分片上传
|
//大于5mb,我们就分片上传
|
||||||
this.ossUploadFileBigMultiable(isProd ? ENDPOINT_INTERNAL : ENDPOINT, requestKey, file);
|
this.ossUploadFileBigMultiable(isProd ? endpointInternal : endpoint, requestKey, file);
|
||||||
} else {
|
} else {
|
||||||
//否则,我们常规上传
|
//否则,我们常规上传
|
||||||
this.ossUploadFileSmall(isProd ? ENDPOINT_INTERNAL : ENDPOINT, requestKey, file);
|
this.ossUploadFileSmall(isProd ? endpointInternal : endpoint, requestKey, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析结果
|
// 解析结果
|
||||||
// 注意,这里可能 需要 replace
|
// 注意,这里可能 需要 replace
|
||||||
String accessPath;
|
String accessPath;
|
||||||
if (StringUtils.isNotBlank(USER_DOMAIN_NAME)) {
|
if (StringUtils.isNotBlank(aliyunOssConfig.getDomain())) {
|
||||||
if (HOST_HTTPS) {
|
accessPath = aliyunOssConfig.getDomain() + "/" + requestKey;
|
||||||
accessPath = "https://" + USER_DOMAIN_NAME + "/" + requestKey;
|
|
||||||
} else {
|
|
||||||
accessPath = "http://" + USER_DOMAIN_NAME + "/" + requestKey;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
accessPath = "https://" + BUCKET_NAME + "." + ENDPOINT + "/" + requestKey;
|
accessPath = "https://" + aliyunOssConfig.getBucketName() + "." + aliyunOssConfig.getEndpoint() + "/" + requestKey;
|
||||||
}
|
}
|
||||||
return accessPath;
|
return accessPath;
|
||||||
}
|
}
|
||||||
|
|
@ -140,7 +109,7 @@ public class AliyunOssFileServiceImpl implements ISysFileService {
|
||||||
/*
|
/*
|
||||||
* Constructs a client instance with your account for accessing OSS
|
* Constructs a client instance with your account for accessing OSS
|
||||||
*/
|
*/
|
||||||
OSS client = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
|
OSS client = new OSSClientBuilder().build(aliyunOssConfig.getEndpoint(), aliyunOssConfig.getAccessKeyId(), aliyunOssConfig.getAccessKeySecret());
|
||||||
String storePath = getStorePath(fileUrl);
|
String storePath = getStorePath(fileUrl);
|
||||||
List<String> keys = new ArrayList<>();
|
List<String> keys = new ArrayList<>();
|
||||||
keys.add(storePath);
|
keys.add(storePath);
|
||||||
|
|
@ -151,7 +120,7 @@ public class AliyunOssFileServiceImpl implements ISysFileService {
|
||||||
*/
|
*/
|
||||||
log.info("\nDeleting all objects:");
|
log.info("\nDeleting all objects:");
|
||||||
DeleteObjectsResult deleteObjectsResult = client.deleteObjects(
|
DeleteObjectsResult deleteObjectsResult = client.deleteObjects(
|
||||||
new DeleteObjectsRequest(BUCKET_NAME).withKeys(keys));
|
new DeleteObjectsRequest(aliyunOssConfig.getBucketName()).withKeys(keys));
|
||||||
List<String> deletedObjects = deleteObjectsResult.getDeletedObjects();
|
List<String> deletedObjects = deleteObjectsResult.getDeletedObjects();
|
||||||
for (String object : deletedObjects) {
|
for (String object : deletedObjects) {
|
||||||
log.info("\t" + object);
|
log.info("\t" + object);
|
||||||
|
|
@ -185,10 +154,13 @@ public class AliyunOssFileServiceImpl implements ISysFileService {
|
||||||
* @return upload/default/20190806202208849_jvs5g.png
|
* @return upload/default/20190806202208849_jvs5g.png
|
||||||
*/
|
*/
|
||||||
private String getStorePath(String filePath) {
|
private String getStorePath(String filePath) {
|
||||||
String publicPath1 = "https://" + BUCKET_NAME + "." + ENDPOINT + "/";
|
String bucketName = aliyunOssConfig.getBucketName();
|
||||||
String publicPath2 = "http://" + BUCKET_NAME + "." + ENDPOINT + "/";
|
String endPoint = aliyunOssConfig.getEndpoint();
|
||||||
String publicPath3 = "https://" + USER_DOMAIN_NAME + "/";
|
String domain = aliyunOssConfig.getDomain();
|
||||||
String publicPath4 = "http://" + USER_DOMAIN_NAME + "/";
|
String publicPath1 = "https://" + bucketName + "." + endPoint + "/";
|
||||||
|
String publicPath2 = "http://" + bucketName + "." + endPoint + "/";
|
||||||
|
String publicPath3 = "https://" + domain + "/";
|
||||||
|
String publicPath4 = "http://" + domain + "/";
|
||||||
//String publicPath5 = ServletCacheUtils.getInstance().getHttpRootPath();
|
//String publicPath5 = ServletCacheUtils.getInstance().getHttpRootPath();
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -209,11 +181,11 @@ public class AliyunOssFileServiceImpl implements ISysFileService {
|
||||||
* demo https://github.com/aliyun/aliyun-oss-java-sdk/blob/master/src/samples/UploadSample.java
|
* demo https://github.com/aliyun/aliyun-oss-java-sdk/blob/master/src/samples/UploadSample.java
|
||||||
*/
|
*/
|
||||||
private String ossUploadFileSmall(String endpoint, String picturePath, MultipartFile file) throws IOException {
|
private String ossUploadFileSmall(String endpoint, String picturePath, MultipartFile file) throws IOException {
|
||||||
OSS ossClient = new OSSClientBuilder().build(endpoint, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
|
OSS ossClient = new OSSClientBuilder().build(endpoint, aliyunOssConfig.getAccessKeyId(), aliyunOssConfig.getAccessKeySecret());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 上传文件 (上传文件流的形式)
|
// 上传文件 (上传文件流的形式)
|
||||||
PutObjectResult putResult = ossClient.putObject(BUCKET_NAME, picturePath, file.getInputStream());
|
PutObjectResult putResult = ossClient.putObject(aliyunOssConfig.getBucketName(), picturePath, file.getInputStream());
|
||||||
} catch (OSSException oe) {
|
} catch (OSSException oe) {
|
||||||
log.error("Caught an OSSException, which means your request made it to OSS, "
|
log.error("Caught an OSSException, which means your request made it to OSS, "
|
||||||
+ "but was rejected with an error response for some reason.");
|
+ "but was rejected with an error response for some reason.");
|
||||||
|
|
@ -285,13 +257,13 @@ public class AliyunOssFileServiceImpl implements ISysFileService {
|
||||||
*/
|
*/
|
||||||
ClientBuilderConfiguration conf = new ClientBuilderConfiguration();
|
ClientBuilderConfiguration conf = new ClientBuilderConfiguration();
|
||||||
conf.setIdleConnectionTime(1000);
|
conf.setIdleConnectionTime(1000);
|
||||||
OSS client = new OSSClientBuilder().build(endpoint, ACCESS_KEY_ID, ACCESS_KEY_SECRET, conf);
|
OSS client = new OSSClientBuilder().build(endpoint, aliyunOssConfig.getAccessKeyId(), aliyunOssConfig.getAccessKeySecret(), conf);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
/*
|
/*
|
||||||
* Claim a upload id firstly
|
* Claim a upload id firstly
|
||||||
*/
|
*/
|
||||||
InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(BUCKET_NAME, requestKey);
|
InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(aliyunOssConfig.getBucketName(), requestKey);
|
||||||
InitiateMultipartUploadResult result = client.initiateMultipartUpload(request);
|
InitiateMultipartUploadResult result = client.initiateMultipartUpload(request);
|
||||||
String uploadId = result.getUploadId();
|
String uploadId = result.getUploadId();
|
||||||
|
|
||||||
|
|
@ -366,7 +338,7 @@ public class AliyunOssFileServiceImpl implements ISysFileService {
|
||||||
if (log.isInfoEnabled()) {
|
if (log.isInfoEnabled()) {
|
||||||
log.info("Fetching an object");
|
log.info("Fetching an object");
|
||||||
}
|
}
|
||||||
OSSObject ossObject = client.getObject(new GetObjectRequest(BUCKET_NAME, requestKey));
|
OSSObject ossObject = client.getObject(new GetObjectRequest(aliyunOssConfig.getBucketName(), requestKey));
|
||||||
if (log.isInfoEnabled()) {
|
if (log.isInfoEnabled()) {
|
||||||
log.info(ossObject.getKey());
|
log.info(ossObject.getKey());
|
||||||
}
|
}
|
||||||
|
|
@ -436,7 +408,7 @@ public class AliyunOssFileServiceImpl implements ISysFileService {
|
||||||
instream.skip(this.startPos);
|
instream.skip(this.startPos);
|
||||||
|
|
||||||
UploadPartRequest uploadPartRequest = new UploadPartRequest();
|
UploadPartRequest uploadPartRequest = new UploadPartRequest();
|
||||||
uploadPartRequest.setBucketName(BUCKET_NAME);
|
uploadPartRequest.setBucketName(aliyunOssConfig.getBucketName());
|
||||||
uploadPartRequest.setKey(this.requestKey);
|
uploadPartRequest.setKey(this.requestKey);
|
||||||
uploadPartRequest.setUploadId(this.uploadId);
|
uploadPartRequest.setUploadId(this.uploadId);
|
||||||
uploadPartRequest.setInputStream(instream);
|
uploadPartRequest.setInputStream(instream);
|
||||||
|
|
@ -474,7 +446,7 @@ public class AliyunOssFileServiceImpl implements ISysFileService {
|
||||||
}
|
}
|
||||||
|
|
||||||
CompleteMultipartUploadRequest completeMultipartUploadRequest =
|
CompleteMultipartUploadRequest completeMultipartUploadRequest =
|
||||||
new CompleteMultipartUploadRequest(BUCKET_NAME, requestKey, uploadId, partETags);
|
new CompleteMultipartUploadRequest(aliyunOssConfig.getBucketName(), requestKey, uploadId, partETags);
|
||||||
client.completeMultipartUpload(completeMultipartUploadRequest);
|
client.completeMultipartUpload(completeMultipartUploadRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -482,7 +454,7 @@ public class AliyunOssFileServiceImpl implements ISysFileService {
|
||||||
if (log.isInfoEnabled()) {
|
if (log.isInfoEnabled()) {
|
||||||
log.info("Listing all parts......");
|
log.info("Listing all parts......");
|
||||||
}
|
}
|
||||||
ListPartsRequest listPartsRequest = new ListPartsRequest(BUCKET_NAME, requestKey, uploadId);
|
ListPartsRequest listPartsRequest = new ListPartsRequest(aliyunOssConfig.getBucketName(), requestKey, uploadId);
|
||||||
PartListing partListing = client.listParts(listPartsRequest);
|
PartListing partListing = client.listParts(listPartsRequest);
|
||||||
|
|
||||||
int partCount = partListing.getParts().size();
|
int partCount = partListing.getParts().size();
|
||||||
|
|
@ -498,8 +470,8 @@ public class AliyunOssFileServiceImpl implements ISysFileService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String listObject() {
|
public String objectsCapacityStr() {
|
||||||
OSS client = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
|
OSS client = new OSSClientBuilder().build(aliyunOssConfig.getEndpoint(), aliyunOssConfig.getAccessKeyId(), aliyunOssConfig.getAccessKeySecret());
|
||||||
final int maxKeys = 200;
|
final int maxKeys = 200;
|
||||||
String nextMarker = null;
|
String nextMarker = null;
|
||||||
ObjectListing objectListing;
|
ObjectListing objectListing;
|
||||||
|
|
@ -509,7 +481,7 @@ public class AliyunOssFileServiceImpl implements ISysFileService {
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
objectListing = client.listObjects(new ListObjectsRequest(BUCKET_NAME).withMarker(nextMarker).withMaxKeys(maxKeys));
|
objectListing = client.listObjects(new ListObjectsRequest(aliyunOssConfig.getBucketName()).withMarker(nextMarker).withMaxKeys(maxKeys));
|
||||||
|
|
||||||
List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
|
List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
|
||||||
for (OSSObjectSummary s : sums) {
|
for (OSSObjectSummary s : sums) {
|
||||||
|
|
@ -552,11 +524,11 @@ public class AliyunOssFileServiceImpl implements ISysFileService {
|
||||||
} catch (MalformedURLException e) {
|
} catch (MalformedURLException e) {
|
||||||
// 忽略
|
// 忽略
|
||||||
}
|
}
|
||||||
OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
|
OSS ossClient = new OSSClientBuilder().build(aliyunOssConfig.getEndpoint(), aliyunOssConfig.getAccessKeyId(), aliyunOssConfig.getAccessKeySecret());
|
||||||
// 设置URL过期时间为12小时,最大值就是43200
|
// 设置URL过期时间为12小时,最大值就是43200
|
||||||
Date expiration = new Date(System.currentTimeMillis() + (43200 * 1000));
|
Date expiration = new Date(System.currentTimeMillis() + (43200 * 1000));
|
||||||
// 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。
|
// 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。
|
||||||
URL url = ossClient.generatePresignedUrl(BUCKET_NAME, objectName, expiration);
|
URL url = ossClient.generatePresignedUrl(aliyunOssConfig.getBucketName(), objectName, expiration);
|
||||||
// 关闭OSSClient。
|
// 关闭OSSClient。
|
||||||
ossClient.shutdown();
|
ossClient.shutdown();
|
||||||
return url.toString();
|
return url.toString();
|
||||||
|
|
@ -8,14 +8,16 @@ import com.amazonaws.auth.BasicAWSCredentials;
|
||||||
import com.amazonaws.services.s3.AmazonS3;
|
import com.amazonaws.services.s3.AmazonS3;
|
||||||
import com.amazonaws.services.s3.AmazonS3Client;
|
import com.amazonaws.services.s3.AmazonS3Client;
|
||||||
import com.amazonaws.services.s3.model.*;
|
import com.amazonaws.services.s3.model.*;
|
||||||
import com.ruoyi.common.core.utils.SpringUtils;
|
import com.ruoyi.common.core.exception.CustomException;
|
||||||
import com.ruoyi.file.utils.FileUploadUtils;
|
import com.ruoyi.file.config.CephConfig;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.io.IOException;
|
import javax.annotation.PostConstruct;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author dazer
|
* @author dazer
|
||||||
|
|
@ -33,39 +35,25 @@ import java.io.IOException;
|
||||||
* 2:ceph存储,使用docker部署 https://www.cnblogs.com/bladeyul/p/10649049.html
|
* 2:ceph存储,使用docker部署 https://www.cnblogs.com/bladeyul/p/10649049.html
|
||||||
* 3:使用docker 搭建 ceph 开发环境,使用aws sdk 存储数据 https://blog.csdn.net/freewebsys/article/details/79553386
|
* 3:使用docker 搭建 ceph 开发环境,使用aws sdk 存储数据 https://blog.csdn.net/freewebsys/article/details/79553386
|
||||||
*/
|
*/
|
||||||
public class CephSysFileServiceImpl implements ISysFileService {
|
@Service
|
||||||
private static final Logger log = LoggerFactory.getLogger(AliyunOssFileServiceImpl.class);
|
public class CephDfsServiceImpl implements IDfsService {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(CephDfsServiceImpl.class);
|
||||||
|
@Autowired
|
||||||
|
private CephConfig cephConfig;
|
||||||
|
|
||||||
protected static AmazonS3 amazonS3 = null;
|
protected static AmazonS3 amazonS3 = null;
|
||||||
/**
|
|
||||||
* s3 提供的 accessKey secretKey
|
|
||||||
* BUCKET_NAME: 概念和阿里云 oss 一模一样
|
|
||||||
*/
|
|
||||||
private static String ACCESS_KEY = "XPVF8TESA1X4SFU*****";
|
|
||||||
private static String SECRET_KEY = "hBBEFpV3qsyI7HAdCBzA2ZdAhuANJFRIUz****";
|
|
||||||
private static String HOST = "127.0.0.1";
|
|
||||||
private static String BUCKET_NAME = "dfwwbook";
|
|
||||||
/**
|
|
||||||
* 域名绑定
|
|
||||||
* USER_DOMAIN_NAME: 域名名称, oss 访问路径绑定的用户自定义域名; 如果没有,就设置为null
|
|
||||||
* hostHttps: 是否开启了https, 需要在控制台配置
|
|
||||||
* https://oss.console.aliyun.com/bucket/oss-cn-shanghai/hiber2019/domain
|
|
||||||
* <p>
|
|
||||||
* private static final String USER_DOMAIN_NAME = "image.jl-media.cn";
|
|
||||||
*/
|
|
||||||
private static final String USER_DOMAIN_NAME = null;
|
|
||||||
private static final boolean HOST_HTTPS = true;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ceph配置初始化
|
* ceph配置初始化
|
||||||
*/
|
*/
|
||||||
static {
|
@PostConstruct
|
||||||
|
void init() {
|
||||||
log.info("开始初始化ceph配置");
|
log.info("开始初始化ceph配置");
|
||||||
AWSCredentials credentials = new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY);
|
AWSCredentials credentials = new BasicAWSCredentials(cephConfig.getAccessKey(), cephConfig.getSecretKey());
|
||||||
ClientConfiguration clientConfiguration = new ClientConfiguration();
|
ClientConfiguration clientConfiguration = new ClientConfiguration();
|
||||||
clientConfiguration.setProtocol(Protocol.HTTP);
|
clientConfiguration.setProtocol(Protocol.HTTP);
|
||||||
amazonS3 = new AmazonS3Client(credentials, clientConfiguration);
|
amazonS3 = new AmazonS3Client(credentials, clientConfiguration);
|
||||||
amazonS3.setEndpoint(HOST);
|
amazonS3.setEndpoint(cephConfig.getEndpoint());
|
||||||
log.info("ceph配置初始化成功");
|
log.info("ceph配置初始化成功");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -109,20 +97,16 @@ public class CephSysFileServiceImpl implements ISysFileService {
|
||||||
|
|
||||||
// long mb5 = 5 * 1024 * 1024L;
|
// long mb5 = 5 * 1024 * 1024L;
|
||||||
//大于5mb,我们就分片上传
|
//大于5mb,我们就分片上传
|
||||||
PutObjectResult result = amazonS3.putObject(BUCKET_NAME, requestKey, file.getInputStream(), new ObjectMetadata());
|
PutObjectResult result = amazonS3.putObject(cephConfig.getBucketName(), requestKey, file.getInputStream(), new ObjectMetadata());
|
||||||
// 上传成功
|
// 上传成功
|
||||||
if (result.isRequesterCharged()) {
|
if (result.isRequesterCharged()) {
|
||||||
// 解析结果
|
// 解析结果
|
||||||
// 注意,这里可能 需要 replace
|
// 注意,这里可能 需要 replace
|
||||||
String accessPath;
|
String accessPath;
|
||||||
if (StringUtils.isNotBlank(USER_DOMAIN_NAME)) {
|
if (StringUtils.isNotBlank(cephConfig.getDomain())) {
|
||||||
if (HOST_HTTPS) {
|
accessPath = cephConfig.getDomain() + "/" + requestKey;
|
||||||
accessPath = "https://" + USER_DOMAIN_NAME + "/" + requestKey;
|
|
||||||
} else {
|
|
||||||
accessPath = "http://" + USER_DOMAIN_NAME + "/" + requestKey;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
accessPath = "https://" + BUCKET_NAME + "/" + requestKey;
|
accessPath = "https://" + cephConfig.getBucketName() + "." + cephConfig.getEndpoint() + "/" + requestKey;
|
||||||
}
|
}
|
||||||
return accessPath;
|
return accessPath;
|
||||||
}
|
}
|
||||||
|
|
@ -135,13 +119,13 @@ public class CephSysFileServiceImpl implements ISysFileService {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
String storePath = getStorePath(fileUrl);
|
String storePath = getStorePath(fileUrl);
|
||||||
amazonS3.deleteObject(BUCKET_NAME, storePath);
|
amazonS3.deleteObject(cephConfig.getBucketName(), storePath);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String listObject() {
|
public String objectsCapacityStr() {
|
||||||
return null;
|
throw new CustomException("ceph-获取文件占用空间功能,敬请期待");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -151,17 +135,15 @@ public class CephSysFileServiceImpl implements ISysFileService {
|
||||||
* @return upload/default/20190806202208849_jvs5g.png
|
* @return upload/default/20190806202208849_jvs5g.png
|
||||||
*/
|
*/
|
||||||
private String getStorePath(String filePath) {
|
private String getStorePath(String filePath) {
|
||||||
String publicPath1 = "https://" + BUCKET_NAME + "/";
|
String publicPath1 = "https://" + cephConfig.getBucketName() + "/";
|
||||||
String publicPath2 = "http://" + BUCKET_NAME + "/";
|
String publicPath2 = "http://" + cephConfig.getBucketName() + "/";
|
||||||
String publicPath3 = "https://" + USER_DOMAIN_NAME + "/";
|
String publicPath3 = "https://" + cephConfig.getDomain() + "/";
|
||||||
String publicPath4 = "http://" + USER_DOMAIN_NAME + "/";
|
String publicPath4 = "http://" + cephConfig.getDomain() + "/";
|
||||||
//String publicPath5 = ServletCacheUtils.getInstance().getHttpRootPath();
|
|
||||||
|
|
||||||
filePath = filePath.replace(publicPath1, "");
|
filePath = filePath.replace(publicPath1, "");
|
||||||
filePath = filePath.replace(publicPath2, "");
|
filePath = filePath.replace(publicPath2, "");
|
||||||
filePath = filePath.replace(publicPath3, "");
|
filePath = filePath.replace(publicPath3, "");
|
||||||
filePath = filePath.replace(publicPath4, "");
|
filePath = filePath.replace(publicPath4, "");
|
||||||
//filePath = filePath.replace(publicPath5, "");
|
|
||||||
return filePath;
|
return filePath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,78 +1,75 @@
|
||||||
package com.ruoyi.file.service;
|
package com.ruoyi.file.service;
|
||||||
|
|
||||||
import com.github.tobato.fastdfs.domain.conn.PooledConnectionFactory;
|
import com.github.tobato.fastdfs.exception.FdfsUnsupportStorePathException;
|
||||||
import com.github.tobato.fastdfs.exception.FdfsUnsupportStorePathException;
|
import com.ruoyi.common.core.exception.CustomException;
|
||||||
import org.apache.commons.io.FilenameUtils;
|
import com.ruoyi.file.config.FastDfsConfig;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
import org.slf4j.Logger;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.Logger;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
|
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
|
||||||
import com.github.tobato.fastdfs.service.FastFileStorageClient;
|
import com.github.tobato.fastdfs.service.FastFileStorageClient;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FastDFS 文件存储
|
* FastDFS 文件存储
|
||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
*/
|
* @see FastDfsConfig
|
||||||
@Service
|
*/
|
||||||
public class FastDfsSysFileServiceImpl implements ISysFileService
|
@Service
|
||||||
{
|
public class FastDfsServiceImpl implements IDfsService
|
||||||
private final Logger logger = LoggerFactory.getLogger(FastDfsSysFileServiceImpl.class);
|
{
|
||||||
/**
|
private final Logger logger = LoggerFactory.getLogger(FastDfsServiceImpl.class);
|
||||||
* 域名或本机访问地址
|
|
||||||
* FastDFS配置 其他参数见:{@link PooledConnectionFactory}
|
@Autowired
|
||||||
*/
|
private FastFileStorageClient storageClient;
|
||||||
@Value("${fdfs.domain}")
|
@Autowired
|
||||||
public String domain;
|
private FastDfsConfig fastDfsConfig;
|
||||||
|
|
||||||
@Autowired
|
/**
|
||||||
private FastFileStorageClient storageClient;
|
* FastDfs文件上传接口
|
||||||
|
*
|
||||||
/**
|
* @param file 上传的文件
|
||||||
* FastDfs文件上传接口
|
* @return 访问地址
|
||||||
*
|
* @throws Exception
|
||||||
* @param file 上传的文件
|
*/
|
||||||
* @return 访问地址
|
@Override
|
||||||
* @throws Exception
|
public String uploadFile(MultipartFile file) throws Exception
|
||||||
*/
|
{
|
||||||
@Override
|
return this.uploadFile(file);
|
||||||
public String uploadFile(MultipartFile file) throws Exception
|
}
|
||||||
{
|
|
||||||
return this.uploadFile(file);
|
@Override
|
||||||
}
|
public String uploadFile(MultipartFile file, String modules) throws Exception {
|
||||||
|
// fastdsf 这里的 modules 没用
|
||||||
@Override
|
validateModule(file, modules);
|
||||||
public String uploadFile(MultipartFile file, String modules) throws Exception {
|
|
||||||
// fastdsf 这里的 modules 没用
|
StorePath storePath = storageClient.uploadFile(file.getInputStream(), file.getSize(),
|
||||||
validateModule(file, modules);
|
FilenameUtils.getExtension(file.getOriginalFilename()), null);
|
||||||
|
|
||||||
StorePath storePath = storageClient.uploadFile(file.getInputStream(), file.getSize(),
|
/// fileUrl = "http://127.0.0.1:22122/" + storePath.getFullPath();
|
||||||
FilenameUtils.getExtension(file.getOriginalFilename()), null);
|
return fastDfsConfig.getDomain() + "/" + storePath.getFullPath();
|
||||||
|
}
|
||||||
/// fileUrl = "http://127.0.0.1:22122/" + storePath.getFullPath();
|
|
||||||
return domain + "/" + storePath.getFullPath();
|
@Override
|
||||||
}
|
public boolean deleteFile(String fileUrl) {
|
||||||
|
if (StringUtils.isEmpty(fileUrl)) {
|
||||||
@Override
|
return false;
|
||||||
public boolean deleteFile(String fileUrl) {
|
}
|
||||||
if (StringUtils.isEmpty(fileUrl)) {
|
try {
|
||||||
return false;
|
StorePath storePath = StorePath.parseFromUrl(fileUrl);
|
||||||
}
|
storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
|
||||||
try {
|
return true;
|
||||||
StorePath storePath = StorePath.parseFromUrl(fileUrl);
|
} catch (FdfsUnsupportStorePathException e) {
|
||||||
storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
|
logger.warn(e.getMessage());
|
||||||
return true;
|
}
|
||||||
} catch (FdfsUnsupportStorePathException e) {
|
return false;
|
||||||
logger.warn(e.getMessage());
|
}
|
||||||
}
|
|
||||||
return false;
|
@Override
|
||||||
}
|
public String objectsCapacityStr() {
|
||||||
|
throw new CustomException("fastdfs-获取文件占用空间功能,敬请期待");
|
||||||
@Override
|
}
|
||||||
public String listObject() {
|
}
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.ruoyi.file.service;
|
||||||
|
|
||||||
import cn.hutool.extra.ftp.Ftp;
|
import cn.hutool.extra.ftp.Ftp;
|
||||||
import cn.hutool.extra.ftp.FtpMode;
|
import cn.hutool.extra.ftp.FtpMode;
|
||||||
|
import com.ruoyi.common.core.exception.CustomException;
|
||||||
import com.ruoyi.file.config.FtpConfig;
|
import com.ruoyi.file.config.FtpConfig;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
@ -15,7 +16,7 @@ import java.io.IOException;
|
||||||
* @author dazer
|
* @author dazer
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class FtpFileServiceImpl implements ISysFileService {
|
public class FtpDfsServiceImpl implements IDfsService {
|
||||||
@Autowired
|
@Autowired
|
||||||
private FtpConfig ftpConfig;
|
private FtpConfig ftpConfig;
|
||||||
public static final String ACCESS_PREFIX = "";
|
public static final String ACCESS_PREFIX = "";
|
||||||
|
|
@ -62,8 +63,8 @@ public class FtpFileServiceImpl implements ISysFileService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String listObject() {
|
public String objectsCapacityStr() {
|
||||||
return null;
|
throw new CustomException("fpt-获取文件占用空间功能,敬请期待");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getStorePath(String filePath) {
|
private String getStorePath(String filePath) {
|
||||||
|
|
@ -1,97 +1,96 @@
|
||||||
package com.ruoyi.file.service;
|
package com.ruoyi.file.service;
|
||||||
|
|
||||||
import com.ruoyi.common.core.exception.file.FileNameLengthLimitExceededException;
|
import com.ruoyi.common.core.exception.file.FileNameLengthLimitExceededException;
|
||||||
import com.ruoyi.common.core.exception.file.InvalidExtensionException;
|
import com.ruoyi.common.core.exception.file.InvalidExtensionException;
|
||||||
import com.ruoyi.common.core.utils.file.MimeTypeUtils;
|
import com.ruoyi.common.core.utils.file.MimeTypeUtils;
|
||||||
import com.ruoyi.file.utils.FileUploadUtils;
|
import com.ruoyi.file.utils.FileUploadUtils;
|
||||||
import org.apache.commons.lang3.RandomStringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.io.IOException;
|
import java.util.Objects;
|
||||||
import java.util.Arrays;
|
import java.util.stream.Collectors;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.stream.Collectors;
|
import static com.ruoyi.file.utils.FileUploadUtils.assertAllowed;
|
||||||
|
import static com.ruoyi.file.utils.FileUploadUtils.extractFilename;
|
||||||
import static com.ruoyi.file.utils.FileUploadUtils.assertAllowed;
|
|
||||||
import static com.ruoyi.file.utils.FileUploadUtils.extractFilename;
|
/**
|
||||||
|
* 【DFS】 = Distributed file system 比 【Sys File】 名称要容易理解
|
||||||
/**
|
* 文件上传接口
|
||||||
* 文件上传接口
|
* 1: default: 最原始的java文件上传
|
||||||
* 1: default: 最原始的java文件上传
|
* 2: ftp 使用ftp模拟文件服务器; 如:iis、linux ftp、vsftpd、FileZilla Server,需要自己搭建服务
|
||||||
* 2: ftp 使用ftp模拟文件服务器; 如:iis、linux ftp、vsftpd、FileZilla Server,需要自己搭建服务
|
* 3: FastDfs 是淘宝开源的分布式文件系统; 淘宝 开发的分布式 dfs, 需要自己搭建服务 (FastDFS)
|
||||||
* 3: FastDfs 是淘宝开源的分布式文件系统; 淘宝 开发的分布式 dfs, 需要自己搭建服务 (FastDFS)
|
* 4: minio 轻量级分布式文件系统; 类似一个阿里云oss、腾讯COS的一个开源、轻量级别的对象存储付;
|
||||||
* 4: minio 轻量级分布式文件系统; 类似一个阿里云oss、腾讯COS的一个开源、轻量级别的对象存储付;
|
* 5: aliyun oss; aliyun oss https://help.aliyun.com/learn/learningpath/oss.html ,需要购买
|
||||||
* 5: aliyun oss; aliyun oss https://help.aliyun.com/learn/learningpath/oss.html ,需要购买
|
* 6: CEPH 分布式大数据文件存储系统 http://docs.ceph.org.cn/
|
||||||
* 6: CEPH 分布式大数据文件存储系统 http://docs.ceph.org.cn/
|
* @author ruoyi
|
||||||
* @author ruoyi
|
*/
|
||||||
*/
|
public interface IDfsService
|
||||||
public interface ISysFileService
|
{
|
||||||
{
|
/**
|
||||||
/**
|
* 允许上传文件存放的目录
|
||||||
* 允许上传文件存放的目录
|
* 不同项目,这里可能做不同的修改;不过不想区分,就default;
|
||||||
* 不同项目,这里可能做不同的修改;不过不想区分,就default;
|
* 项目稍微大一些,如果不区分目录,后期要做删除 or 迁移就很麻烦;
|
||||||
* 项目稍微大一些,如果不区分目录,后期要做删除 or 迁移就很麻烦;
|
*/
|
||||||
*/
|
String[] DEFAULT_MODULES_NAME = {
|
||||||
String[] DEFAULT_MODULES_NAME = {
|
// 图片
|
||||||
// 图片
|
"default", "banner", "product", "images", "music",
|
||||||
"default", "banner", "product", "images", "music",
|
// pdf
|
||||||
// pdf
|
"pdf" };
|
||||||
"pdf" };
|
|
||||||
|
/**
|
||||||
/**
|
* 文件上传接口
|
||||||
* 文件上传接口
|
*
|
||||||
*
|
* @param file 上传的文件
|
||||||
* @param file 上传的文件
|
* @return 访问地址
|
||||||
* @return 访问地址
|
* @throws Exception
|
||||||
* @throws Exception
|
*/
|
||||||
*/
|
String uploadFile(MultipartFile file) throws Exception;
|
||||||
String uploadFile(MultipartFile file) throws Exception;
|
|
||||||
|
String uploadFile(MultipartFile file, String modules) throws Exception;
|
||||||
String uploadFile(MultipartFile file, String modules) throws Exception;
|
|
||||||
|
/**
|
||||||
/**
|
* 删除文件
|
||||||
* 删除文件
|
*
|
||||||
*
|
* @param fileUrl 文件访问地址,全路径或者不是全路径都可以
|
||||||
* @param fileUrl 文件访问地址,全路径或者不是全路径都可以
|
* @return
|
||||||
* @return
|
*/
|
||||||
*/
|
boolean deleteFile(String fileUrl);
|
||||||
boolean deleteFile(String fileUrl);
|
|
||||||
|
/**
|
||||||
/**
|
* 获取文件占用空间
|
||||||
* 获取文件占用空间
|
* 别名:objectsCapacity
|
||||||
* 别名:objectsCapacity
|
* @return 文件大小字符串,eg: 100MB、2G
|
||||||
* @return 文件大小字符串,eg: 100MB、2G
|
*/
|
||||||
*/
|
String objectsCapacityStr();
|
||||||
String listObject();
|
|
||||||
|
/**
|
||||||
/**
|
* 校验文件名称长度 & 校验文件大小 & 校验上传的目录是否是项目中注册了的 & 返回新的文件名称
|
||||||
* 校验文件名称长度 & 校验文件大小 & 校验上传的目录是否是项目中注册了的 & 返回新的文件名称
|
*
|
||||||
*
|
* @param file 文件
|
||||||
* @param file 文件
|
* @param modules 模块,这里作为上传的文件夹使用;eg: 项目中有banner、video、music、txt、product、default 多个模块,不同模块存放到不同文件夹中;
|
||||||
* @param modules 模块,这里作为上传的文件夹使用;eg: 项目中有banner、video、music、txt、product、default 多个模块,不同模块存放到不同文件夹中;
|
* @return 新的系统生成的文件名称
|
||||||
* @return 新的系统生成的文件名称
|
* @throws InvalidExtensionException
|
||||||
* @throws InvalidExtensionException
|
*/
|
||||||
*/
|
default String validateModule(MultipartFile file, String modules) throws InvalidExtensionException {
|
||||||
default String validateModule(MultipartFile file, String modules) throws InvalidExtensionException {
|
Objects.requireNonNull(file, "文件不能为空!");
|
||||||
Objects.requireNonNull(file, "文件不能为空!");
|
modules = StringUtils.defaultString(modules, "default");
|
||||||
modules = StringUtils.defaultString(modules, "default");
|
|
||||||
|
//1、这里校验上传文件的模块,如果没有注册,直接报错
|
||||||
//1、这里校验上传文件的模块,如果没有注册,直接报错
|
if (!Arrays.stream(DEFAULT_MODULES_NAME).collect(Collectors.toList()).contains(modules)) {
|
||||||
if (!Arrays.stream(DEFAULT_MODULES_NAME).collect(Collectors.toList()).contains(modules)) {
|
throw new RuntimeException("上传模块" + modules + "不存在,请现在 'FolderPath.UploadModules'中注册. 枚举值,请参见Home接口:api/getFolderPath");
|
||||||
throw new RuntimeException("上传模块" + modules + "不存在,请现在 'FolderPath.UploadModules'中注册. 枚举值,请参见Home接口:api/getFolderPath");
|
}
|
||||||
}
|
|
||||||
|
// 2、校验文件名称长度
|
||||||
// 2、校验文件名称长度
|
/// String ext = (String.valueOf(file.getOriginalFilename()).substring(String.valueOf(file.getOriginalFilename()).lastIndexOf("."))).toLowerCase();
|
||||||
/// String ext = (String.valueOf(file.getOriginalFilename()).substring(String.valueOf(file.getOriginalFilename()).lastIndexOf("."))).toLowerCase();
|
int fileNamelength = file.getOriginalFilename().length();
|
||||||
int fileNamelength = file.getOriginalFilename().length();
|
if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
|
||||||
if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
|
{
|
||||||
{
|
throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
|
||||||
throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
|
}
|
||||||
}
|
|
||||||
|
// 3、文件大小校验
|
||||||
// 3、文件大小校验
|
assertAllowed(file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
|
||||||
assertAllowed(file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
|
return modules + "/" + extractFilename(file);
|
||||||
return modules + "/" + extractFilename(file);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
@ -1,69 +1,58 @@
|
||||||
package com.ruoyi.file.service;
|
package com.ruoyi.file.service;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import com.ruoyi.common.core.exception.CustomException;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import com.ruoyi.file.config.LocalConfig;
|
||||||
import org.springframework.context.annotation.Primary;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.context.annotation.Primary;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.stereotype.Service;
|
||||||
import com.ruoyi.file.utils.FileUploadUtils;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import com.ruoyi.file.utils.FileUploadUtils;
|
||||||
/**
|
|
||||||
* 本地文件存储
|
/**
|
||||||
*
|
* 本地文件存储
|
||||||
* @author ruoyi
|
*
|
||||||
*/
|
* @author ruoyi
|
||||||
@Primary
|
*/
|
||||||
@Service
|
@Primary
|
||||||
public class LocalSysFileServiceImpl implements ISysFileService
|
@Service
|
||||||
{
|
public class LocalDfsServiceImpl implements IDfsService
|
||||||
/**
|
{
|
||||||
* 资源映射路径 前缀
|
private final LocalConfig localConfig;
|
||||||
* eg: eg: /statics
|
|
||||||
*/
|
public LocalDfsServiceImpl(LocalConfig localConfig) {
|
||||||
@Value("${file.prefix}")
|
this.localConfig = localConfig;
|
||||||
public String localFilePrefix;
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 域名或本机访问地址
|
* 本地文件上传接口
|
||||||
* eg: http://127.0.0.1:9300
|
*
|
||||||
*/
|
* @param file 上传的文件
|
||||||
@Value("${file.domain}")
|
* @return 访问地址
|
||||||
public String domain;
|
* @throws Exception
|
||||||
|
*/
|
||||||
/**
|
@Override
|
||||||
* 上传文件存储在本地的根路径
|
public String uploadFile(MultipartFile file) throws Exception
|
||||||
* eg: D:/ruoyi/uploadPath
|
{
|
||||||
*/
|
return this.uploadFile(file, null);
|
||||||
@Value("${file.path}")
|
}
|
||||||
private String localFilePath;
|
|
||||||
|
@Override
|
||||||
/**
|
public String uploadFile(MultipartFile file, String modules) throws Exception {
|
||||||
* 本地文件上传接口
|
String localFilePath = localConfig.getLocalFilePath();
|
||||||
*
|
String domain = localConfig.getDomain();
|
||||||
* @param file 上传的文件
|
String localFilePrefix = localConfig.getLocalFilePrefix();
|
||||||
* @return 访问地址
|
|
||||||
* @throws Exception
|
String name = FileUploadUtils.upload(localFilePath + "/" + StringUtils.defaultString(modules, ""), file);
|
||||||
*/
|
return domain + localFilePrefix + name;
|
||||||
@Override
|
}
|
||||||
public String uploadFile(MultipartFile file) throws Exception
|
|
||||||
{
|
@Override
|
||||||
return this.uploadFile(file, null);
|
public boolean deleteFile(String fileUrl) {
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public String uploadFile(MultipartFile file, String modules) throws Exception {
|
@Override
|
||||||
String name = FileUploadUtils.upload(localFilePath + "/" + StringUtils.defaultString(modules, ""), file);
|
public String objectsCapacityStr() {
|
||||||
String url = domain + localFilePrefix + name;
|
throw new CustomException("本地存储-获取文件占用空间功能,敬请期待");
|
||||||
return url;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean deleteFile(String fileUrl) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String listObject() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,90 +1,90 @@
|
||||||
package com.ruoyi.file.service;
|
package com.ruoyi.file.service;
|
||||||
|
|
||||||
import cn.hutool.extra.spring.SpringUtil;
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
import io.minio.RemoveObjectArgs;
|
import com.ruoyi.common.core.exception.CustomException;
|
||||||
import io.minio.errors.*;
|
import io.minio.RemoveObjectArgs;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import io.minio.errors.*;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.stereotype.Service;
|
||||||
import com.ruoyi.file.config.MinioConfig;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import com.ruoyi.file.utils.FileUploadUtils;
|
import com.ruoyi.file.config.MinioConfig;
|
||||||
import io.minio.MinioClient;
|
import io.minio.MinioClient;
|
||||||
import io.minio.PutObjectArgs;
|
import io.minio.PutObjectArgs;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Minio 文件存储
|
* Minio 文件存储
|
||||||
*
|
*
|
||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class MinioSysFileServiceImpl implements ISysFileService
|
public class MinioDfsServiceImpl implements IDfsService
|
||||||
{
|
{
|
||||||
@Autowired
|
@Autowired
|
||||||
private MinioConfig minioConfig;
|
private MinioConfig minioConfig;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private MinioClient client;
|
private MinioClient client;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 本地文件上传接口
|
* 本地文件上传接口
|
||||||
*
|
*
|
||||||
* @param file 上传的文件
|
* @param file 上传的文件
|
||||||
* @return 访问地址
|
* @return 访问地址
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String uploadFile(MultipartFile file) throws Exception
|
public String uploadFile(MultipartFile file) throws Exception
|
||||||
{
|
{
|
||||||
return this.uploadFile(file, null);
|
return this.uploadFile(file, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String uploadFile(MultipartFile file, String modules) throws Exception {
|
public String uploadFile(MultipartFile file, String modules) throws Exception {
|
||||||
String fileName = validateModule(file ,modules);
|
String fileName = validateModule(file ,modules);
|
||||||
boolean isProd = "prod".equalsIgnoreCase(SpringUtil.getActiveProfile());
|
boolean isProd = "prod".equalsIgnoreCase(SpringUtil.getActiveProfile());
|
||||||
if (!isProd) {
|
if (!isProd) {
|
||||||
fileName = SpringUtil.getActiveProfile() + "/" + fileName;
|
fileName = SpringUtil.getActiveProfile() + "/" + fileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
PutObjectArgs args = PutObjectArgs.builder()
|
PutObjectArgs args = PutObjectArgs.builder()
|
||||||
.bucket(minioConfig.getBucketName())
|
.bucket(minioConfig.getBucketName())
|
||||||
.object(fileName)
|
.object(fileName)
|
||||||
.stream(file.getInputStream(), file.getSize(), -1)
|
.stream(file.getInputStream(), file.getSize(), -1)
|
||||||
.contentType(file.getContentType())
|
.contentType(file.getContentType())
|
||||||
.build();
|
.build();
|
||||||
client.putObject(args);
|
client.putObject(args);
|
||||||
return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + fileName;
|
return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + fileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean deleteFile(String fileUrl) {
|
public boolean deleteFile(String fileUrl) {
|
||||||
RemoveObjectArgs args = RemoveObjectArgs.builder().
|
RemoveObjectArgs args = RemoveObjectArgs.builder().
|
||||||
bucket(minioConfig.getBucketName()).
|
bucket(minioConfig.getBucketName()).
|
||||||
object(fileUrl).
|
object(fileUrl).
|
||||||
build();
|
build();
|
||||||
try {
|
try {
|
||||||
client.removeObject(args);
|
client.removeObject(args);
|
||||||
return true;
|
return true;
|
||||||
} catch (ErrorResponseException |
|
} catch (ErrorResponseException |
|
||||||
InsufficientDataException |
|
InsufficientDataException |
|
||||||
InternalException |
|
InternalException |
|
||||||
InvalidKeyException |
|
InvalidKeyException |
|
||||||
InvalidResponseException |
|
InvalidResponseException |
|
||||||
IOException |
|
IOException |
|
||||||
NoSuchAlgorithmException |
|
NoSuchAlgorithmException |
|
||||||
ServerException |
|
ServerException |
|
||||||
XmlParserException e) {
|
XmlParserException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String listObject() {
|
public String objectsCapacityStr() {
|
||||||
return null;
|
throw new CustomException("minio存储-获取文件占用空间功能,敬请期待");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,143 @@
|
||||||
|
package com.ruoyi.file.service;
|
||||||
|
|
||||||
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
|
import com.alibaba.nacos.shaded.com.google.gson.Gson;
|
||||||
|
import com.qiniu.common.QiniuException;
|
||||||
|
import com.qiniu.http.Response;
|
||||||
|
import com.qiniu.storage.BucketManager;
|
||||||
|
import com.qiniu.storage.Configuration;
|
||||||
|
import com.qiniu.storage.Region;
|
||||||
|
import com.qiniu.storage.UploadManager;
|
||||||
|
import com.qiniu.storage.model.DefaultPutRet;
|
||||||
|
import com.qiniu.util.Auth;
|
||||||
|
import com.ruoyi.common.core.exception.CustomException;
|
||||||
|
import com.ruoyi.file.config.QiniuKodoConfig;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 七牛云 kodo 文件存储封装
|
||||||
|
*
|
||||||
|
* @author dazer
|
||||||
|
* @see QiniuKodoConfig
|
||||||
|
* 参考:https://developer.qiniu.com/kodo/1239/java#upload-stream
|
||||||
|
* 路径:【对象存储==>JAVASDK==>文件上传==>数据流上传】
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class QiniuDfsServiceImpl implements IDfsService {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(QiniuDfsServiceImpl.class);
|
||||||
|
@Autowired
|
||||||
|
private QiniuKodoConfig qiniuKodoConfig;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String uploadFile(MultipartFile file) throws Exception {
|
||||||
|
return this.uploadFile(file, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String uploadFile(MultipartFile file, String modules) throws Exception {
|
||||||
|
//key: 这里不能以/开头
|
||||||
|
String newName = validateModule(file, null);
|
||||||
|
//key: 这里不能以/开头
|
||||||
|
String requestKey = "upload/" + "/" + newName;
|
||||||
|
//这里增加一个前缀区分一下是测试环境还是正式环境
|
||||||
|
boolean isProd = "prod".equalsIgnoreCase(SpringUtil.getActiveProfile());
|
||||||
|
if (!isProd) {
|
||||||
|
requestKey = SpringUtil.getActiveProfile() + "/" + requestKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
Configuration cfg = new Configuration(getCurrentRegion());
|
||||||
|
//...其他参数参考类注释
|
||||||
|
UploadManager uploadManager = new UploadManager(cfg);
|
||||||
|
|
||||||
|
String accessKey = qiniuKodoConfig.getAccessKey();
|
||||||
|
String secretKey = qiniuKodoConfig.getSecretKey();
|
||||||
|
String bucket = qiniuKodoConfig.getBucketName();
|
||||||
|
//默认不指定key的情况下,以文件内容的hash值作为文件名
|
||||||
|
String key = requestKey;
|
||||||
|
|
||||||
|
InputStream byteInputStream = file.getInputStream();
|
||||||
|
Auth auth = Auth.create(accessKey, secretKey);
|
||||||
|
String upToken = auth.uploadToken(bucket);
|
||||||
|
try {
|
||||||
|
Response response = uploadManager.put(byteInputStream, key, upToken, null, null);
|
||||||
|
//解析上传成功的结果
|
||||||
|
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
|
||||||
|
System.out.println(putRet.key);
|
||||||
|
System.out.println(putRet.hash);
|
||||||
|
} catch (QiniuException ex) {
|
||||||
|
Response r = ex.response;
|
||||||
|
String json = null;
|
||||||
|
try {
|
||||||
|
json = r.bodyString();
|
||||||
|
} catch (QiniuException e) {
|
||||||
|
log.error(e.getMessage());
|
||||||
|
}
|
||||||
|
log.error("【七牛云】-上传文件- 失败,原因1:" + r);
|
||||||
|
log.error("【七牛云】-上传文件-失败,原因2:" + json);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteFile(String fileUrl) {
|
||||||
|
Configuration cfg = new Configuration(getCurrentRegion());
|
||||||
|
|
||||||
|
//...其他参数参考类注释
|
||||||
|
String accessKey = qiniuKodoConfig.getAccessKey();
|
||||||
|
String secretKey = qiniuKodoConfig.getSecretKey();
|
||||||
|
String bucket = qiniuKodoConfig.getBucketName();
|
||||||
|
Auth auth = Auth.create(accessKey, secretKey);
|
||||||
|
BucketManager bucketManager = new BucketManager(auth, cfg);
|
||||||
|
|
||||||
|
String key = getStorePath(fileUrl);
|
||||||
|
try {
|
||||||
|
bucketManager.delete(bucket, key);
|
||||||
|
} catch (QiniuException ex) {
|
||||||
|
//如果遇到异常,说明删除失败
|
||||||
|
log.error("【七牛云】-删除文件-失败 code:" + ex.code() + "=>" + ex.response.toString());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String objectsCapacityStr() {
|
||||||
|
throw new CustomException("七牛云-获取文件占用空间功能,敬请期待");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换url
|
||||||
|
*
|
||||||
|
* @param filePath http://guangdong-oss.ityun.ltd/upload/default/header.jpg
|
||||||
|
* @return upload/default/header.jpg
|
||||||
|
*
|
||||||
|
* http://qwc2geifw.hn-bkt.clouddn.com/upload/default/header.jpg
|
||||||
|
* ==> upload/default/header.jpg
|
||||||
|
*/
|
||||||
|
private String getStorePath(String filePath) {
|
||||||
|
String domain = qiniuKodoConfig.getDomain();
|
||||||
|
String publicPath3 = domain + "/";
|
||||||
|
filePath = filePath.replace(publicPath3, "");
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 存储区域 https://developer.qiniu.com/kodo/1671/region-endpoint-fq
|
||||||
|
* new Region.Builder()
|
||||||
|
* https://developer.qiniu.com/kodo/1239/java#upload-stream
|
||||||
|
* 自定义区域域名: 搜索【其中关于Region对象和机房的关系如下:】
|
||||||
|
* @return 存储区域
|
||||||
|
*/
|
||||||
|
private Region getCurrentRegion() {
|
||||||
|
/// 其中关于Region对象和机房的关系如下:
|
||||||
|
///Region region = Region.autoRegion();
|
||||||
|
///Region region = Region.region0();
|
||||||
|
//构造一个带指定 Region 对象的配置类
|
||||||
|
return Region.huadong();
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue