multipartFile.transferTo相对路径(multipartfile和file互转)

在Java开发中,避免不了会使用if-else,无可厚非,if-else确实简单而又快捷地实现了大量的业务逻辑分叉走向。但是如果使用大量if-else会使得逻辑显得复杂,一段时间之后,阅读也会比较困难,这个时候,可以考虑方法的原子性,一个方法或者一个类只实现一个功能。诸如:设计模式、枚举、三元运算等等,来优化if-else。本文主要介绍策略模式来优化if-else。

场景:一个文件上传,根据选择的存储位置,可以存到:本地、阿里云、腾讯云、AWS等。

当然可以直接使用if-else,来进行文件上传处理。但是这样显得比较臃肿,代码扩展性不好。

所以我采用策略模式,来优化代码

1、提供一个策略接口

public interface StorageStrategy {    /**     * 匹配策略的key,处理策略的唯一标识,不可重复     *     * @return key     */    Integer strategyKey();    /**     * 存储软件包信息     *     * @param multipartFile     * @param uploadBO     * @throws Exception     */    void storageInfo(MultipartFile multipartFile, UploadBO uploadBO) throws Exception;}

2、本地存储策略

/** * 本地文件相关信息 * * @Author admin * @Date 2021/8/17 16:50 * @Description: */@Componentpublic class LocalStorageStrategy implements StorageStrategy {    @Resource    private FileInfoMapper fileInfoMapper;    @Value("${storage.local-path:}")    private String localPath;    @Override    public Integer strategyKey() {        return StorageEnum.LOCAL_STORAGE.getCode();    }    @Override    public void storageSoftPackageInfo(MultipartFile multipartFile, UploadBO uploadBO) throws Exception {        String fileName = multipartFile.getOriginalFilename();        String fileTotalName = localPath + File.separator + fileName;        File f = new File(fileTotalName);        multipartFile.transferTo(f);        FileInfoPO fileInfoPO = new FileInfoPO();        CopyUtils.copyEntity(uploadBO, fileInfoPO);        fileInfoPO.setOriginName(fileName);        fileInfoPO.setOriginPath(localPath);        fileInfoPO.setCreatedDate(new Date());        fileInfoPO.setChannel(0);        // 保存信息        fileInfoMapper.insert(fileInfoPO);    }

3、阿里云存储

/** * 阿里云存储相关信息 * * @Author admin * @Date 2021/8/17 16:50 * @Description: */@Componentpublic class AliYunStorageStrategy implements StorageStrategy {       @Override    public Integer strategyKey() {        return StorageSoftPackageEnum.ALIYUN_STORAGE.getCode();    }    @Override    public void storageSoftPackageInfo(MultipartFile multipartFile, UploadSoftPackageBO uploadSoftPackageBO) throws Exception {        // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。        String endpoint = "yourEndpoint";        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。        String accessKeyId = "yourAccessKeyId";        String accessKeySecret = "yourAccessKeySecret";        // 创建OSSClient实例。        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);        // 填写本地文件的完整路径。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。        InputStream inputStream = new FileInputStream("D:\\localpath\\examplefile.txt");        // 依次填写Bucket名称(例如examplebucket)和Object完整路径(例如exampledir/exampleobject.txt)。Object完整路径中不能包含Bucket名称。        ossClient.putObject("examplebucket", "exampledir/exampleobject.txt", inputStream);        // 关闭OSSClient。        ossClient.shutdown();      // TODO 。。。。。。。    }}

4、注解存储策略到容器

@Component@Slf4jpublic class StorageStrategyHandler implements InitializingBean, ApplicationContextAware {    /**     * 注册中心,存放策略的map     */    private final Map<Integer, StorageStrategy> fileStrategyServiceMap = new ConcurrentHashMap<>(16);    /**     * spring的上下文     */    private ApplicationContext applicationContext;    /**     * 将StrategyService的类都按照定义好的规则(strategyKey),放入fileStrategyServiceMap中     */    @Override    public void afterPropertiesSet() {        //初识化把所有的策略bean        Map<String, StorageStrategy> matchBeans = applicationContext.getBeansOfType(StorageStrategy.class);        //策略注入的bean做key,策略实现类做value        matchBeans.forEach((key, value) -> {            fileStrategyServiceMap.put(value.strategyKey(), value);            log.info("初始化软件包上传方式策略模式的键值对: key={},value={}", key, value);        });    }    /**     * 注入applicationContext     *     * @param applicationContext     * @throws BeansException     */    @Override    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {        this.applicationContext = applicationContext;    }    /**     * 通过key获取对应的策略实现     *     * @param key     * @return     */    public StorageStrategy getStrategy(int key) {        return fileStrategyServiceMap.get(key);    }

4、策略枚举值

public enum StorageEnum {    LOCAL_STORAGE(0, "本地存储"),    ALIYUN_STORAGE(1, "阿里云存储"),    TENCENT_CLOUD_STORAGE(2, "腾讯云存储"),    AWS_STORAGE(3, "亚马逊云存储");    private Integer code;    private String desc;    private StorageEnum(int code, String desc) {        this.code = code;        this.desc = desc;    }    @Override    public String toString() {        return code + desc;    }    public Integer getCode() {        return code;    }    public void setCode(Integer code) {        this.code = code;    }    public String getDesc() {        return desc;    }    public void setDesc(String desc) {        this.desc = desc;    }}

5、调用对应的策略

 // 调用文件存储策略 StorageStrategy storageStrategy = storageStrategyHandler.getStrategy(StorageEnum.LOCAL_STORAGE.getCode()); storageStrategy.storageInfo(multipartFile, uploadBO);

这样即可调用对应的策略,如果需要新增一种文件存储的方式,如腾讯云,只需要增加策略实现既可以如下:

@Componentpublic class TencentYunStorageStrategy implements StorageStrategy {    @Override    public Integer strategyKey() {        return StorageEnum.TENCENT_CLOUD_STORAGE.getCode();    }    @Override    public void storageInfo(MultipartFile multipartFile, UploadBO uploadBO) throws Exception {    }}

好的代码,需要时间不断地打磨和积累,没有捷径,加油!

本站部分内容由互联网用户自发贡献,该文观点仅代表作者本人,本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如发现本站有涉嫌抄袭侵权/违法违规等内容,请联系我们举报!一经查实,本站将立刻删除。