SpringBoot 文件操作 整合思路

文件上传后,不仅可以保存在部署应用的服务器,也可以保存在阿里云,华为云obs,本文主要分享 SpringBoot 整合这三种不同文件存储服务器的思路

1.既然要实现存储到三种不同的文件存储服务器,那自然想到接口和实现类,然后将实现类提供给 controller 调用。为了在程序中方便的知道实现类的简单类名和全类名来进行测试,可以新建一个抽象类。
接口

public interface FileService {
    FileInfoVo upload(MultipartFile multipartFile);
    String getSimpleClassName();
    String getFullClassName();
}

抽象类

public abstract class AbstractFileServiceImpl implements FileService {
    @Override
    public String getSimpleClassName() {
        return this.getClass().getSimpleName();
    }

    @Override
    public String getFullClassName() {
        return this.getClass().getName();
    }
}

三个实现类

// 文件上传到部署应用的服务器
@Service
public class LocalFileServiceImpl extends AbstractFileServiceImpl {
    @Override
    public FileInfoVo upload(MultipartFile multipartFile) {
        return null;
    }
}

// 文件上传到阿里云
@Service
public class AliyunFileServiceImpl extends AbstractFileServiceImpl {
    @Override
    public FileInfoVo upload(MultipartFile multipartFile) {
        return null;
    }
}

// 文件上传到华为 obs
@Service
public class HuaweiObsFileServiceImpl extends AbstractFileServiceImpl {
    @Override
    public FileInfoVo upload(MultipartFile multipartFile) {
        return null;
    }
}

2.具体实现文件相关操作的逻辑如果写在 service 里,不利于程序的扩展,所以我们再新建三个工具类给 service 实现类调用,所以需要在三个 service 实现类中注入对应的工具类,同时由于在工具类中写的都是具体的功能实现逻辑,想要上传到阿里云华为云,就需要参考官网,进行导包和相应的配置
导包


<dependency>
    <groupId>com.aliyun.ossgroupId>
    <artifactId>aliyun-sdk-ossartifactId>
    <verison>3.15.1version>
    <optional>trueoptional>
dependency>


<dependency>
    <groupId>com.huaweicloudgroupId>
    <artifactId>esdk-obs-java-bundleartifactId>
    <verison>3.22.12version>
    <optional>trueoptional>
dependency>

配置文件

# appliation.yml 文件
file:
  local:
    path: xxx
  aliyun:
    endpoint: xxx
    access-key-id: xxx
    access-key-secret: xxx
    bucket-name: xxx
  huawei-obs:
    endpoint: xxx
    access-key-id: xxx
    access-key-secret: xxx
    bucket-name: xxx

配置类

// 文件上传到部署应用的服务器的配置类
@Configuration
public class LocalFileConfig {
    @Bean
    public LocalFileUtil localFileUtil() {
        return new LocalFileUtil();
    }
}

// 文件上传到阿里云的配置类
@Configuration
public class AliyunFileConfig {
    @Value("${file.aliyun.endpoint:}")
    private String endpoint;
    @Value("${file.aliyun.access-key-id:}")
    private String accessKeyId;
    @Value("${file.aliyun.access-key-secret:}")
    private String accessKeySecret;

    /**
     * 阿里云文件存储 client
     */
    @Bean
    public OSSClient ossClient() {
        return new OSSClient(endpoint, accessKeyId, accessKeySecret);
    }

    @Bean
    public AliyunFileUtil aliyunFileUtil() {
        return new AliyunFileUtil();
    }
}

// 文件上传到华为 obs 的配置类
@Configuration
public class HuaweiObsConfig {
    @Value("${file.huawei-obs.endpoint:}")
    private String endpoint;
    @Value("${file.huawei-obs.access-key-id:}")
    private String accessKeyId;
    @Value("${file.huawei-obs.access-key-secret:}")
    private String accessKeySecret;

    @Bean
    public ObsClient obsClient() {
        return new ObsClient(accessKeyId, accessKeySecret, endpoint);
    }

    @Bean
    public HuaweiObsFileUtil huaweiObsFileUtil() {
        return new HuaweiObsFileUtil();
    }
}

工具类

// 文件上传到部署应用的服务器的工具类
public class LocalFileUtil {
    public FileInfoVo upload(MultipartFile file) {
        return null;
    }
}

// 文件上传到阿里云的工具类
public class AliyunFileUtil {
    @Value("${file.aliyun.bucket-name:}")
    private String bucketName;

    public FileInfoVo upload(MultipartFile file) {
        return null;
    }
}

// 文件上传到华为 obs 的工具类
public class HuaweiObsFileUtil {
    @Value("${file.huawei-obs.bucket-name:}")
    private String bucketName;

    public FileInfoVo upload(MultipartFile file) {
        return null;
    }
}

service 实现类

// 文件上传到部署应用的服务器
@Service
public class LocalFileServiceImpl extends AbstractFileServiceImpl {
    @Resource
    private LocalFileUtil localFileUtil;

    @Override
    public FileInfoVo upload(MultipartFile multipartFile) {
        // 自己写具体的上传逻辑
        return localFileUtil.upload(multipartFile);
    }
}

// 文件上传到阿里云
@Service
public class AliyunFileServiceImpl extends AbstractFileServiceImpl {
    @Resource
    private AliyunFileUtil aliyunFileUtil;

    @Override
    public FileInfoVo upload(MultipartFile multipartFile) {
        // 参考阿里云示例程序写具体的上传逻辑
        return aliyunFileUtil.upload(multipartFile);
    }
}

// 文件上传到华为 obs
@Service
public class HuaweiObsFileServiceImpl extends AbstractFileServiceImpl {
    @Resource
    private HuaweiObsFileUtil huaweiObsFileUtil;

    @Override
    public FileInfoVo upload(MultipartFile multipartFile) {
        // 参考华为云 obs 示例程序写具体的上传逻辑
        return huaweiObsFileUtil.upload(multipartFile);
    }
}

3.这样就可以在 controller 中注入三个实现类来调用方法了,当然为了后续扩展方便,可以通过 factory 类和枚举类来获得 service 实现类,然后在 controller 中注入 factory 类,通过 factory 来获得 service 实现类
枚举类

@Getter
public enum FileUploadTypeEnum {
    LOCAL("0", FileConstants.LOCAL_FILE_SERVICE_BEAN),
    ALIYUN("1", FileConstants.ALIYUN_FILE_SERVICE_BEAN),
    HUAWEI_OBS("2", FileConstants.HUAWEI_OBS_FILE_SERVICE_BEAN);
    private final String code;
    private final String desc;

    FileUploadTypeEnum(String code, String desc) {
        this.code = code;
        this.desc = desc;
    }

    public static FileUploadTypeEnum getFileUploadTypeEnumByCode(String code) {
        for (FileUploadTypeEnum fileUploadTypeEnum : FileUploadTypeEnum.values()) {
            if (fileUploadTypeEnum.getCode().equals(code)) {
                return fileUploadTypeEnum;
            }
        }
        return null;
    }
}

常量类

public interface FileConstants {
    // FileService 实例   值为 beanName
    String LOCAL_FILE_SERVICE_BEAN = "localFileServiceImpl";
    String ALIYUN_FILE_SERVICE_BEAN = "aliyunFileServiceImpl";
    String HUAWEI_OBS_FILE_SERVICE_BEAN = "huaweiObsFileServiceImpl";
}

factory 类

@Component
public class FileServiceFactory {
    // beanMap 的结构: key: beanName  value: FileService 实例
    private Map<String, FileService> beanMap = new HashMap<>();
    @Resource
    private ApplicationContextUtil applicationContextUtil;

    @PostConstruct
    private void initFileService() {
        beanMap = applicationContextUtil.getApplicationContext().getBeansOfType(FileService.class);
    }

    public FileService getFileService(FileUploadTypeEnum typeEnum) {
        return beanMap.get(typeEnum.getDesc());
    }
}

ApplicationContextUtil

@Component
public class ApplicationContextUtil implements ApplicationContextAware {
    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public ApplicationContext getApplicationContext() {
        return this.applicationContext;
    }
}

4.在 controller 中通过 factory 来获取 service 实例,调用相关方法。

以上就是本文的全部内容,希望对大家有所帮助,如有错误欢迎指正!!!

你可能感兴趣的:(spring,boot,后端,java)