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 { }}
好的代码,需要时间不断地打磨和积累,没有捷径,加油!
本站部分内容由互联网用户自发贡献,该文观点仅代表作者本人,本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规等内容,请联系我们举报!一经查实,本站将立刻删除。