SpringBoot——策略模式切换文件上传方式
本文最后更新于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.配合前端页面实现切换文件上传平台

后续更新……

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇