本文最后更新于334 天前,其中的信息可能已经过时,如有错误请发送邮件到woaldyy@foxmail.com
1.编写策略接口
1-1.新建strategy文件夹,并创建策略接口
public interface UploadStrategy {
/**
* 上传文件
* @param file 文件
* @return 文件访问路径
*/
String uploadFile(MultipartFile file,String path);
}
2.完善项目的配置文件信息
2-1.添加项目依赖(七牛云、阿里云、腾讯云等)
<!-- 阿里云Oss -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.8.3</version>
</dependency>
<!-- 腾讯云Cos -->
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
<version>5.6.89</version>
</dependency>
<!-- 七牛云Kodo -->
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>7.13.1</version>
</dependency>
2.2完善yml文件配置信息
# 七牛云为例
qiniu:
accessKey: ****************************************
secretKey: ****************************************
bucket: ****************************************
zone: ****************************************
domain: ****************************************
2.3编写Properties类交给Spring管理,方便后续取到yml文件中的值
/**
* @ConfigurationProperties(prefix = "xxxx.qiniu")
* "xxxx.qiniu"根据yml文件结构而定
*/
@Getter
@Setter
@Component
@ConfigurationProperties(prefix = "xxxx.qiniu")
public class QiniuProperties {
private String accessKey;
private String secretKey;
private String bucket;
private String zone;
private String domain;
}
2.4编写存储桶配置信息(七牛云为例)
在config目录下创建QiniuConfig配置类,初始化部分信息,简化后续初始化操作
@org.springframework.context.annotation.Configuration
public class QiniuConfig {
@Resource
private QiniuProperties qiniuProperties;
/**
* 获取Auth
* @return Auth
*/
@Bean
public Auth getAuth(){
return Auth.create(qiniuProperties.getAccessKey(),qiniuProperties.getSecretKey());
}
/**
* 获取Configuration
* @return Configuration
*/
@Bean
public Configuration getConfiguration(){
return new Configuration(Region.huanan());
}
/**
* 获取UploadManager
* @return UploadManager
*/
@Bean
public UploadManager getUploadManager(){
return new UploadManager(getConfiguration());
}
/**
* 获取BucketManager
* @return BucketManager
*/
@Bean
public BucketManager getBucketManager(){
return new BucketManager(getAuth(),getConfiguration());
}
}
3.策略接口实现类
3-1.抽象实现类
具体文件上传所涉及到的功能。
- 上传对象初始化
- 文件是否已经存在
- 文件上传
- 获取访问路径
所以直接定义一个抽象类来规定需要使用的方法,然后每个实现类继承该抽象类
@Getter
@Setter
public abstract class AbstractUploadStrategyImpl implements UploadStrategy {
@Override
public String uploadFile(MultipartFile file,String filePath) {
//获取文件名 -> 生成相对路径
try {
String extName = file.getOriginalFilename();
String fileRelativePath ="image/"+ filePath + extName;
//初始化
initClient();
executeUpload(file,fileRelativePath);
return getPublicNetworkAccessUrl(fileRelativePath);
} catch (IOException e) {
throw new UploadFileFailException(e.getMessage());
}
}
/**
* 初始化客户端
*/
public abstract void initClient();
/**
* 检查文件是否已经存在(文件MD5值唯一)
*
* @param fileRelativePath 文件相对路径
* @return true 已经存在 false 不存在
*/
public abstract boolean checkFileIsExisted(String fileRelativePath);
/**
* 执行上传操作
*
* @param file 文件
* @param fileRelativePath 文件相对路径
* @throws IOException io异常信息
*/
public abstract void executeUpload(MultipartFile file, String fileRelativePath) throws IOException;
/**
* 获取公网访问路径
*
* @param fileRelativePath 文件相对路径
* @return 公网访问绝对路径
*/
public abstract String getPublicNetworkAccessUrl(String fileRelativePath);
}
3.2七牛云Kodo实现类
注意:UploadFileFailException为自定义的异常类,不需要可以直接把相关代码删除即可。
@Slf4j
@Service("qiniuKodoUploadStrategyImpl")
public class QiniuKodoUploadStrategyImpl extends AbstractUploadStrategyImpl{
/**
* 鉴权
*/
@Resource
private Auth auth;
/**
* 上传凭证
*/
private String upToken;
/**
* 七牛云配置
*/
@Resource
private QiniuProperties qiniuProperties;
/**
* 上传管理器
*/
@Resource
private UploadManager uploadManager;
/**
* 配置
*/
@Resource
private Configuration cfg;
/**
* 存储桶Manager
*/
@Resource
private BucketManager bucketManager;
@Override
public void initClient() {
upToken = auth.uploadToken(qiniuProperties.getBucket());
cfg.resumableUploadAPIVersion = Configuration.ResumableUploadAPIVersion.V2;
log.info("OssClient Init Success...");
}
@Override
public boolean checkFileIsExisted(String fileRelativePath) {
return false;
}
@Override
public void executeUpload(MultipartFile file, String fileRelativePath) {
try {
byte[] fileBytes = file.getBytes();
try {
Response response = uploadManager.put(fileBytes, fileRelativePath, upToken);
//解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
} catch (QiniuException ex) {
ex.printStackTrace();
if (ex.response != null) {
try {
String body = ex.response.toString();
System.err.println(body);
} catch (Exception e) {
throw new UploadFileFailException(e.getMessage());
}
}
throw new UploadFileFailException(ex.getMessage());
}
} catch (IOException e) {
throw new UploadFileFailException(e.getMessage());
}
}
@Override
public String getPublicNetworkAccessUrl(String fileRelativePath) {
return qiniuProperties.getDomain() + fileRelativePath;
}
}
4.策略上下文实现
通过策略上下文来选择使用哪种上传方式。
注意点:
当Map集合的Value为接口类型时,Spring会自动对Map集合进行注入。
- 其中map集合的key为接口对应实现类的BeanName
- 其中map集合的vlaue为接口对应实现类的实例
其中传入的 uploadServiceName就是对应策略类所规定的的BeanName,这里的BeanName就作为选择的条件。
@Component
@RequiredArgsConstructor
public class UploadStrategyContext {
private final Map<String, UploadStrategy> uploadStrategyMap;
public String executeUploadStrategy(MultipartFile file, final String filePath, String uploadServiceName) {
// 执行特点的上传策略
return uploadStrategyMap.get(uploadServiceName).uploadFile(file, filePath);
}
}
5.配合前端页面实现切换文件上传平台
后续更新……