zoukankan      html  css  js  c++  java
  • SpringBoot实现云存储功能

    一、引入相应云平台SDK

        <dependency>
                <groupId>com.qiniu</groupId>
                <artifactId>qiniu-java-sdk</artifactId>
                <version>${qiniu.version}</version>
            </dependency>
            <dependency>
                <groupId>com.aliyun.oss</groupId>
                <artifactId>aliyun-sdk-oss</artifactId>
                <version>${aliyun.oss.version}</version>
            </dependency>
            <dependency>
                <groupId>com.qcloud</groupId>
                <artifactId>cos_api</artifactId>
                <version>${qcloud.cos.version}</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.slf4j</groupId>
                        <artifactId>slf4j-log4j12</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>

    二、定义抽象类 CloudStorageService ,用来声明上传的公共接口,如下所示:

    /**
     * 云存储(支持七牛、阿里云、腾讯云、又拍云)
     *
     */
    public abstract class CloudStorageService {
        /** 云存储配置信息 */
        CloudStorageConfig config;
    
        /**
         * 文件路径
         * @param prefix 前缀
         * @param suffix 后缀
         * @return 返回上传路径
         */
        public String getPath(String prefix, String suffix) {
            //生成uuid
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
            //文件路径
            String path = DateUtils.format(new Date(), "yyyyMMdd") + "/" + uuid;
    
            if(StringUtils.isNotBlank(prefix)){
                path = prefix + "/" + path;
            }
    
            return path + suffix;
        }
    
        /**
         * 文件上传
         * @param data    文件字节数组
         * @param path    文件路径,包含文件名
         * @return        返回http地址
         */
        public abstract String upload(byte[] data, String path);
    
        /**
         * 文件上传
         * @param data     文件字节数组
         * @param suffix   后缀
         * @return         返回http地址
         */
        public abstract String uploadSuffix(byte[] data, String suffix);
    
        /**
         * 文件上传
         * @param inputStream   字节流
         * @param path          文件路径,包含文件名
         * @return              返回http地址
         */
        public abstract String upload(InputStream inputStream, String path);
    
        /**
         * 文件上传
         * @param inputStream  字节流
         * @param suffix       后缀
         * @return             返回http地址
         */
        public abstract String uploadSuffix(InputStream inputStream, String suffix);
    
    }
    View Code

     三、

      1、七牛上传的实现,只需继承 CloudStorageService ,并实现相应的上传接口,如下所示:

    /**
     * 七牛云存储
     *
     */
    public class QiniuCloudStorageService extends CloudStorageService {
        private UploadManager uploadManager;
        private String token;
    
        public QiniuCloudStorageService(CloudStorageConfig config){
            this.config = config;
    
            //初始化
            init();
        }
    
        private void init(){
            uploadManager = new UploadManager(new Configuration(Zone.autoZone()));
            token = Auth.create(config.getQiniuAccessKey(), config.getQiniuSecretKey()).
                    uploadToken(config.getQiniuBucketName());
        }
    
        @Override
        public String upload(byte[] data, String path) {
            try {
                Response res = uploadManager.put(data, path, token);
                if (!res.isOK()) {
                    throw new RuntimeException("上传七牛出错:" + res.toString());
                }
            } catch (Exception e) {
                throw new RRException("上传文件失败,请核对七牛配置信息", e);
            }
    
            return config.getQiniuDomain() + "/" + path;
        }
    
        @Override
        public String upload(InputStream inputStream, String path) {
            try {
                byte[] data = IOUtils.toByteArray(inputStream);
                return this.upload(data, path);
            } catch (IOException e) {
                throw new RRException("上传文件失败", e);
            }
        }
    
        @Override
        public String uploadSuffix(byte[] data, String suffix) {
            return upload(data, getPath(config.getQiniuPrefix(), suffix));
        }
    
        @Override
        public String uploadSuffix(InputStream inputStream, String suffix) {
            return upload(inputStream, getPath(config.getQiniuPrefix(), suffix));
        }
    }
    View Code

      2、腾讯云上传的实现,只需继承 CloudStorageService ,并实现相应的上传接口,如下所示:

    /**
     * 腾讯云存储
     *
     */
    public class QcloudCloudStorageService extends CloudStorageService {
        private COSClient client;
    
        public QcloudCloudStorageService(CloudStorageConfig config){
            this.config = config;
    
            //初始化
            init();
        }
    
        private void init(){
            Credentials credentials = new Credentials(config.getQcloudAppId(), config.getQcloudSecretId(),
                    config.getQcloudSecretKey());
            
            //初始化客户端配置
            ClientConfig clientConfig = new ClientConfig();
            //设置bucket所在的区域,华南:gz 华北:tj 华东:sh
            clientConfig.setRegion(config.getQcloudRegion());
            
            client = new COSClient(clientConfig, credentials);
        }
    
        @Override
        public String upload(byte[] data, String path) {
            //腾讯云必需要以"/"开头
            if(!path.startsWith("/")) {
                path = "/" + path;
            }
            
            //上传到腾讯云
            UploadFileRequest request = new UploadFileRequest(config.getQcloudBucketName(), path, data);
            String response = client.uploadFile(request);
    
            JSONObject jsonObject = JSONObject.parseObject(response);
            if(jsonObject.getInteger("code") != 0) {
                throw new RRException("文件上传失败," + jsonObject.getString("message"));
            }
    
            return config.getQcloudDomain() + path;
        }
    
        @Override
        public String upload(InputStream inputStream, String path) {
            try {
                byte[] data = IOUtils.toByteArray(inputStream);
                return this.upload(data, path);
            } catch (IOException e) {
                throw new RRException("上传文件失败", e);
            }
        }
    
        @Override
        public String uploadSuffix(byte[] data, String suffix) {
            return upload(data, getPath(config.getQcloudPrefix(), suffix));
        }
    
        @Override
        public String uploadSuffix(InputStream inputStream, String suffix) {
            return upload(inputStream, getPath(config.getQcloudPrefix(), suffix));
        }
    }
    View Code

      3、腾讯云上传的实现,只需继承 CloudStorageService ,并实现相应的上传接口,如下所示:

    /**
     * 阿里云存储
     *
     */
    public class AliyunCloudStorageService extends CloudStorageService {
        private OSSClient client;
    
        public AliyunCloudStorageService(CloudStorageConfig config){
            this.config = config;
    
            //初始化
            init();
        }
    
        private void init(){
            client = new OSSClient(config.getAliyunEndPoint(), config.getAliyunAccessKeyId(),
                    config.getAliyunAccessKeySecret());
        }
    
        @Override
        public String upload(byte[] data, String path) {
            return upload(new ByteArrayInputStream(data), path);
        }
    
        @Override
        public String upload(InputStream inputStream, String path) {
            try {
                client.putObject(config.getAliyunBucketName(), path, inputStream);
            } catch (Exception e){
                throw new RRException("上传文件失败,请检查配置信息", e);
            }
    
            return config.getAliyunDomain() + "/" + path;
        }
    
        @Override
        public String uploadSuffix(byte[] data, String suffix) {
            return upload(data, getPath(config.getAliyunPrefix(), suffix));
        }
    
        @Override
        public String uploadSuffix(InputStream inputStream, String suffix) {
            return upload(inputStream, getPath(config.getAliyunPrefix(), suffix));
        }
    }
    View Code

    四、对外提供了OSSFactory工厂,可方便业务的调用,如下所示: 

    /**
     * 文件上传Factory
     *
     */
    public final class OSSFactory {
        private static SysConfigService sysConfigService;
    
        static {
            OSSFactory.sysConfigService = (SysConfigService) SpringContextUtils.getBean("sysConfigService");
        }
    
        public static CloudStorageService build(){
            //获取云存储配置信息
            CloudStorageConfig config = sysConfigService.getConfigObject(ConfigConstant.CLOUD_STORAGE_CONFIG_KEY, CloudStorageConfig.class);
    
            if(config.getType() == Constant.CloudService.QINIU.getValue()){
                return new QiniuCloudStorageService(config);
            }else if(config.getType() == Constant.CloudService.ALIYUN.getValue()){
                return new AliyunCloudStorageService(config);
            }else if(config.getType() == Constant.CloudService.QCLOUD.getValue()){
                return new QcloudCloudStorageService(config);
            }
    
            return null;
        }
    
    }
    View Code

    五、文件上传的例子,如下: 

        /**
         * 上传文件
         */
        @PostMapping("/upload")
        @RequiresPermissions("sys:oss:all")
        public R upload(@RequestParam("file") MultipartFile file) throws Exception {
            if (file.isEmpty()) {
                throw new RRException("上传文件不能为空");
            }
    
            //获取上传文件后缀
            String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
            //上传到aliyun/qiniucloud/Qcloud,并返回地址url
            String url = OSSFactory.build().uploadSuffix(file.getBytes(), suffix);
    
            //保存文件信息
            SysOssEntity ossEntity = new SysOssEntity();
            ossEntity.setUrl(url);
            ossEntity.setCreateDate(new Date());
            sysOssService.save(ossEntity);
    
            return R.ok().put("url", url);
        }

    一个小小后端的爬行痕迹
  • 相关阅读:
    php关于网页乱码问题
    EditPlus编写PHP使用技巧
    Dedecms当前位置(面包屑导航)的处理
    css有关鼠标移动上去图片变透明度变化
    CSS之Position详解
    如何修改FlashFXP默认编辑工具使用记事本打开
    ecshop点击订购、加入按钮没反应的解决方法
    kindEditor完整认识 PHP上调用并上传图片说明
    OpenCV 实现分水岭算法
    OpenCV 矩形轮廓检测
  • 原文地址:https://www.cnblogs.com/heikedeblack/p/14982257.html
Copyright © 2011-2022 走看看