SpringBoot 策略模式实现切换上传文件模式

 更新时间:2023年11月20日 12:03:48   作者:草木物语  
策略模式是指有一定行动内容的相对稳定的策略名称,这篇文章主要介绍了SpringBoot 策略模式 切换上传文件模式,需要的朋友可以参考下

SpringBoot 策略模式

策略模式是指有一定行动内容的相对稳定的策略名称。

  • 我们定义一个接口(就比如接下来要实现的文件上传接口)
  • 我们定义所需要实现的策略实现类 A、B、C、D(也就是项目中所使用的四种策略阿里云Oss上传、腾讯云Cos上传、七牛云Kodo上传、本地上传)
  • 我们通过策略上下文来调用策略接口,并选择所需要使用的策略

策略接口

public interface UploadStrategy {
    /**
     * 上传文件
     *
     * @param file     文件
     * @param filePath 文件上传露肩
     * @return {@link String} 文件上传的全路径
     */
    String uploadFile(MultipartFile file, final String filePath);  

策略实现类内部实现

@Getter
@Setter
public abstract class AbstractUploadStrategyImpl implements UploadStrategy {
    @Override
    public String uploadFile(MultipartFile file, String filePath) {
        try {
            //region 获取文件md5值 -> 获取文件后缀名 -> 生成相对路径
            String fileMd5 = XcFileUtil.getMd5(file.getInputStream());
            String extName = XcFileUtil.getExtName(file.getOriginalFilename());
            String fileRelativePath = filePath + fileMd5 + extName;
            //endregion
            //region 初始化
            initClient();
            //endregion
            //region 检测文件是否已经存在,不存在则进行上传操作
            if (!checkFileIsExisted(fileRelativePath)) {
                executeUpload(file, fileRelativePath);
            }
            //endregion
            return getPublicNetworkAccessUrl(fileRelativePath);
        } catch (IOException e) {
            throw new XcException("文件上传失败");
        }
    }
    /**
     * 初始化客户端
     */
    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);
}  

本地上传策略具体实现

@Slf4j
@Getter
@Setter
@RequiredArgsConstructor
@Service("localUploadServiceImpl")
public class LocalUploadStrategyImpl extends AbstractUploadStrategyImpl {
    /**
     * 本地项目端口
     */
    @Value("${server.port}")
    private Integer port;
    /**
     * 前置路径 ip/域名
     */
    private String prefixUrl;
    /**
     * 构造器注入bean
     */
    private final ObjectStoreProperties properties;
    @Override
    public void initClient() {
        try {
            prefixUrl = ResourceUtils.getURL("classpath:").getPath() + "static/";
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            throw new XcException("文件不存在");
        }
        log.info("initClient Init Success...");
    }
    @Override
    public boolean checkFileIsExisted(String fileRelativePath) {
        return new File(prefixUrl + fileRelativePath).exists();
    }
    @Override
    public void executeUpload(MultipartFile file, String fileRelativePath) throws IOException {
        File dest = checkFolderIsExisted(fileRelativePath);
        try {
            file.transferTo(dest);
        } catch (IOException e) {
            e.printStackTrace();
            throw new XcException("文件上传失败");
        }
    }
    @Override
    public String getPublicNetworkAccessUrl(String fileRelativePath) {
        try {
            String host = InetAddress.getLocalHost().getHostAddress();
            if (StringUtils.isEmpty(properties.getLocal().getDomainUrl())) {
                return String.format("http://%s:%d%s", host, port, fileRelativePath);
            }
            return properties.getLocal().getDomainUrl() + fileRelativePath;
        } catch (UnknownHostException e) {
            throw new XcException("HttpCodeEnum.UNKNOWN_ERROR");
        }
    }
    /**
     * 检查文件夹是否存在,若不存在则创建文件夹,最终返回上传文件
     *
     * @param fileRelativePath 文件相对路径
     * @return {@link  File} 文件
     */
    private File checkFolderIsExisted(String fileRelativePath) {
        File rootPath = new File(prefixUrl + fileRelativePath);
        if (!rootPath.exists()) {
            if (!rootPath.mkdirs()) {
                throw new XcException("文件夹创建失败");
            }
        }
        return rootPath;
    }
}  

策略上下文实现

@Component
@RequiredArgsConstructor
public class UploadStrategyContext {
    private final Map<String, UploadStrategy> uploadStrategyMap;
    /**
     * 执行上传策略
     *
     * @param file     文件
     * @param filePath 文件上传路径前缀
     * @return {@link String} 文件上传全路径
     */
    public String executeUploadStrategy(MultipartFile file, final String filePath, String uploadServiceName) {
        // 执行特定的上传策略
        return uploadStrategyMap.get(uploadServiceName).uploadFile(file, filePath);
    }
}

上传测试

参考资料:

文章来源:https://mp.weixin.qq.com/s/Bi7tFfKHXpBkXNpbTMR2lg

案例代码:https://gitcode.net/nanshen__/store-object

到此这篇关于SpringBoot 策略模式 切换上传文件模式的文章就介绍到这了,更多相关SpringBoot 策略模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • spring boot自定义配置源操作步骤

    spring boot自定义配置源操作步骤

    这篇文章主要介绍了spring boot自定义配置源操作步骤,需要的朋友可以参考下
    2017-10-10
  • Spring中的@ComponentScan注解详解

    Spring中的@ComponentScan注解详解

    这篇文章主要介绍了Spring中的@ComponentScan注解详解,ComponentScan做的事情就是告诉Spring从哪里找到bean,由你来定义哪些包需要被扫描,一旦你指定了,Spring将会在被指定的包及其下级包中寻找bean,需要的朋友可以参考下
    2024-01-01
  • SpringBoot实现统一功能处理的教程详解

    SpringBoot实现统一功能处理的教程详解

    这篇文章主要为大家详细介绍了SpringBoot如何实现统一功能处理,文中的示例代码讲解详细,对大家学习或工作有一定借鉴价值,感兴趣的同学可以参考阅读下
    2023-05-05
  • Java使用freemarker实现word下载方式

    Java使用freemarker实现word下载方式

    文章介绍了如何使用FreeMarker实现Word文件下载,包括引用依赖、创建Word模板、将Word文件存为XML格式、更改后缀为FTL模板、处理图片和代码实现
    2025-02-02
  • 详解JavaScript中的函数声明和函数表达式

    详解JavaScript中的函数声明和函数表达式

    这篇文章主要介绍了详解JavaScript中的函数声明和函数表达式,是JS入门学习中的基础知识,需要的朋友可以参考下
    2015-08-08
  • Spring Cloud工程搭建过程详解

    Spring Cloud工程搭建过程详解

    文章介绍了如何使用父子工程搭建SpringCloud项目,包括创建父工程和子项目,以及管理依赖版本,感兴趣的朋友一起看看吧
    2025-02-02
  • 归并排序时间复杂度过程推导详解

    归并排序时间复杂度过程推导详解

    这篇文章主要介绍了C语言实现排序算法之归并排序,对归并排序的原理及实现过程做了非常详细的解读,需要的朋友可以参考下,希望能帮助到你
    2021-08-08
  • 关于StringUtils.isBlank()的使用及说明

    关于StringUtils.isBlank()的使用及说明

    这篇文章主要介绍了关于StringUtils.isBlank()的使用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • java自定义注解实现前后台参数校验的实例

    java自定义注解实现前后台参数校验的实例

    下面小编就为大家带来一篇java自定义注解实现前后台参数校验的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-11-11
  • 解决@DateTimeFormat格式化时间出错问题

    解决@DateTimeFormat格式化时间出错问题

    这篇文章主要介绍了解决@DateTimeFormat格式化时间出错问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12

最新评论