【SpringBoot 】策略模式 :一键切换文件上传方式

1.什么是策略模式

在策略模式中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为模式。在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的上下文对象。策略对象更改上下文对象的执行算法。

2.策略模式具体实现

2.1 创建项目

新建一个SpringBoot项目

2.2 策略接口
  • 首先我们新建一个名称为 strategy 的文件夹(在代码规范中,使用设计模式要明确的体现出来,便于后期维护)
  • 代码如下
/**
 * @Author: hec
 * @Date: 2024/4/5
 * @Email: 2740860037@qq.com
 * @Description: 文件上传策略接口
 */
public interface UploadStrategy {

    R upload(MultipartFile img);
}

2.3 配置文件
  • 总体配置文件
# 上传模式 策略模式 可选 oss或local
upload:
  mode: local
  local:
    url: # 访问路径
    path: # 文件存储路径
  aliyun:
    url: # 访问路径
    endpoint: # 地区节点
    keyid: # keyid
    keysecret: # keysecret
    bucketname: # 桶名称
  qiniu:
    url: # 访问路径
    accessKey: # accessKey
    accessSecretKey: # accessSecretKey
    bucketname: # 桶名称

2.4 策略内部实现
2.4.1 本地上传
/**
 * @Author: hec
 * @Date: 2024/4/5
 * @Email: 2740860037@qq.com
 * @Description: 本地上传实现
 */
@Service
public class LocalUploadStrategyImpl implements UploadStrategy {

    @Value("${upload.local.url}")
    private String url;

    @Value("${upload.local.path}")
    private String path;

    @Override
    public R upload(MultipartFile img) {
        try {
            String filename = img.getOriginalFilename();
            String uuid = UUID.randomUUID().toString().replace("-", "");
            filename = uuid + filename;

            String datePath = new DateTime().toString("yyyyMMdd");
            filename = datePath + "/" + filename;
            // 判断目录是否存在
            File directory = new File(path + datePath);
            if (!directory.exists()){
                directory.mkdirs();
            }
            File newFile = new File(path + filename);
            img.transferTo(newFile);
            String fileUrl = url + filename;
            return R.okResult(fileUrl);
        } catch (IOException e) {
            e.printStackTrace();
            throw new ServiceException(HttpCodeEnum.FILE_TYPE_ERROR);
        }
    }
}

2.4.2 阿里云OSS
  • 读取配置文件信息
@Data
@Configuration
@ConfigurationProperties(prefix = "upload.aliyun")
public class AliYunConfigProperties {

    //读取配置文件内容
    private String url;

    private String endpoint;

    private String keyId;

    private String keySecret;

    private String bucketName;
}
  • 实现代码
/**
 * @Author: hec
 * @Date: 2024/4/5
 * @Email: 2740860037@qq.com
 * @Description: 阿里云上传实现
 */
@Service
public class AliYunUploadStrategyImpl implements UploadStrategy {

    @Autowired
    AliYunConfigProperties aliYunConfigProperties;

    @Override
    public R upload(MultipartFile img) {
        try {
            OSS ossClient = new OSSClientBuilder().build(aliYunConfigProperties.getEndpoint(),
                    aliYunConfigProperties.getKeyId(), aliYunConfigProperties.getKeySecret());

            InputStream inputStream = img.getInputStream();
            String filename = img.getOriginalFilename();
            String uuid = UUID.randomUUID().toString().replace("-", "");
            filename = uuid + filename;

            String datePath = new DateTime().toString("yyyy/MM/dd");
            filename = datePath + "/" + filename;

            ossClient.putObject(aliYunConfigProperties.getBucketName(), filename, inputStream);

            ossClient.shutdown();

            String url = aliYunConfigProperties.getUrl() + filename;
            return R.okResult(url);
        } catch (IOException e) {
            e.printStackTrace();
            throw new ServiceException(HttpCodeEnum.FILE_TYPE_ERROR);
        }
    }
}

2.4.3 七牛云OSS
  • 读取配置信息
@Data
@Configuration
@ConfigurationProperties(prefix = "upload.qiniu")
public class QiNiuConfigProperties {

    //读取配置文件内容
    private String url;

    private String accessKey;

    private String accessSecretKey;

    private String bucketName;
}
  • 代码实现
/**
 * @Author: hec
 * @Date: 2024/4/5
 * @Email: 2740860037@qq.com
 * @Description: 七牛云文件上传实现
 */
@Service
public class QiNiuUploadStrategyImpl implements UploadStrategy {

    @Autowired
    QiNiuConfigProperties qiNiuConfigProperties;

    @Override
    public R upload(MultipartFile img) {
        try {
            // 指定 Region 对象的配置类  根据自己的对象空间的地址选
            Configuration configuration = new Configuration(Region.huanan());
            UploadManager uploadManager = new UploadManager(configuration);
            // 获取七牛云提供的 token
            Auth auth = Auth.create(qiNiuConfigProperties.getAccessKey(), qiNiuConfigProperties.getAccessSecretKey());
            String upToken = auth.uploadToken(qiNiuConfigProperties.getBucketName());

            byte[] fileBytes = img.getBytes();
            String filename = img.getOriginalFilename();
            String uuid = UUID.randomUUID().toString().replace("-", "");
            filename = uuid + filename;

            String datePath = new DateTime().toString("yyyy/MM/dd");
            filename = datePath + "/" + filename;

            uploadManager.put(fileBytes,filename,upToken);
            String url = qiNiuConfigProperties.getUrl() + filename;
            return R.okResult(url);
        } catch (IOException e) {
            e.printStackTrace();
            throw new ServiceException(HttpCodeEnum.FILE_TYPE_ERROR);
        }
    }
}
2.5 策略上下文
  • 新建策略枚举类
@Getter
@AllArgsConstructor
public enum UploadModeEnum {

    /**
     * aliyun
     */
    AliYun("aliyun", "aliYunUploadStrategyImpl"),
    /**
     * 千牛云
     */
    QiNiu("qiniu", "qiNiuUploadStrategyImpl"),
    /**
     * 本地
     */
    LOCAL("local", "localUploadStrategyImpl");


    /**
     * 模式
     */
    private final String mode;

    /**
     * 策略
     */
    private final String strategy;

    /**
     * 获取策略
     *
     * @param mode 模式
     * @return {@link String} 搜索策略
     */
    public static String getStrategy(String mode) {
        for (UploadModeEnum value : UploadModeEnum.values()) {
            if (value.getMode().equals(mode)) {
                return value.getStrategy();
            }
        }
        return null;
    }

}
  • 代码实现
/**
 * @Author: hec
 * @Date: 2024/4/5
 * @Email: 2740860037@qq.com
 * @Description: 文件上传上下文
 */
@Service
public class UploadStrategyContext {

    /**
     * 上传模式
     */
    @Value("${upload.mode}")
    private String uploadMode;

    @Autowired
    private Map<String, UploadStrategy> uploadStrategyMap;

    /**
     * 执行上传策略
     *
     * @param img 文件
     * @return {@link R} 文件地址
     */
    public R executeUploadStrategy(MultipartFile img) {
        return uploadStrategyMap.get(getStrategy(uploadMode)).upload(img);
    }
}

3.总结

上述只是对于策略模式的简单实践。
我们可以通过网站全局配制结合前端界面来完成选择使用哪个平台来进行文件的上传。
当我们选中哪种上传模式,那么后台则会执行该上传方式

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

头发减一.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值