阿里云OSS上传目录代码备忘

本文记录了一个可以作为Spring Bean使用的阿里云OSS上传目录的完整API,由于阿里云OSS本身不支持直接上传目录,因此这个API为项目需求提供了便利,避免每次重复编写相同代码。
摘要由CSDN通过智能技术生成

阿里云OSS没有直接上传目录的API,恰巧项目需要,就写了个比较完备的API,可直接copy当做spring bean用,每次都从头写太麻烦,还是记录下来用吧。

package com.shinewonder.ad.springcomponent;

import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.HttpMethod;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.common.auth.Credentials;
import com.aliyun.oss.common.comm.ResponseMessage;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.*;
import com.aliyun.oss.model.SetBucketCORSRequest.CORSRule;

/**
 * @comment 阿里云OSS工具类,直接@Autowired,然后使用即可
 */
@Component
public class GlobalALiYunOSSUtil implements OSS {
   
    private Logger logger = LoggerFactory.getLogger(getClass().getTypeName());
    @Value("#{learncfg['aliOSS.endpoint']}")
    private String endpoint;
    @Value("#{learncfg['aliOSS.accessKeyId']}")
    private String accessKeyId;
    @Value("#{learncfg['aliOSS.accessKeySecret']}")
    private String accessKeySecret;
    @Value("#{learncfg['aliOSS.file.rootdir']}")
    private String OSSFileRootdir;
    private OSS ossClient;

    @PostConstruct
    private void initMethod() {
   
        ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    }

    @PreDestroy
    private void destroyMethod() {
   
        ossClient.shutdown();
    }

    /**
     * 向OSS上传目录及其所包含的所有文件
     * 例:目录/A/B/C下有文件1.txt,则最终css存储的kay为prefixPath/C/1.txt,即prefixPath+目录名+目录下文件相对路径
     * @param bucketName
     * @param prefixPath
     * @param rootDir 必须是绝对路径
     * @param checkFileExist true:检测文件是否已在OSS存在,文件不存在则上传到OSS,文件存在则不再上传到OSS,false:不检测文件是否已在OSS存在,直接上传到OSS
     * @param infoMap 可传入一个ConcurrentHashMap,putDirectory会以infoKey为map的key,把当前进行中的OSS的key放在infoMap中,外界则可以通过infoMap.get(infoKey)拿到当前正在往OSS上传的文件的key
     * @param infoKey map的key,可自定义,绝不能重复,否则会导致拿到的信息错乱,infoMap或infoKey只要有一个为null,则外界不可通过infoMap拿到正在进行中OSS的key
     * @return true 上传成功
     */
    public boolean putDirectory(final String bucketName, final String prefixPath, final File rootDir, final boolean checkFileExist, final ConcurrentHashMap<String, String> infoMap,
            final String infoKey) {
   
        boolean r = true;
        if (!(rootDir.isDirectory() && rootDir.isAbsolute())) {
    //检测根目录合法性
            throw new IllegalArgumentException("root dir must exist and is absolute.");
        }
        ConcurrentLinkedQueue<File> folders = new ConcurrentLinkedQueue<>(); //声明需要遍历的文件夹列表
        folders.add(rootDir); //将根目录放入遍历列表
        String key = "";
        for (File file = folders.poll(); file != null; file = folders.poll()) {
    //遍历文件夹遍历列表
            File[] temFiles = file.listFiles();
            for (File f : temFiles) {
   
                if (f.isDirectory()) {
    //是目录,放入文件夹遍历列表4
                    folders.add(f);
                } else {
    //是文件,上传到阿里OSS
                    key = "";
                    key += OSSFileRootdir + "/";
                    key += prefixPath + "/";
                    key += f.getAbsolutePath().substring(rootDir.getParent().length());
                    key = key.replaceAll("[\\\\/]+", "/");
                    if (infoMap != null && infoKey != null) {
   
                        infoMap.put(infoKey, key); //将当前进行中的key放入infoKey
                    }
                    if (checkFileExist) {
    //首先检测文件是否已经在OSS上存在
                        boolean exist = false;
                        try {
   
                            exist = ossClient.doesObjectExist(bucketName, key);
                        } catch (Exception e) {
   
                            try {
   
                                exist = ossClient.doesObjectExist(bucketName, key);
                            } catch (Exception e1) {
   
                                try {
   
                                    exist = ossClient.doesObjectExist(bucketName, key);
                                } catch (Exception e2) {
   
                                    logger.warn("check file is exist on OSS fail:{}|{}|{}", bucketName, key, f.getAbsolutePath());
                                    throw e2;
                                }
                            }
                        }
                        if (!exist) {
    //若不在OSS上存在,则上传到OSS
                            try {
   
                                ossClient.putObject(bucketName, key, f);
                            } catch (Exception e) {
   
                                try {
   
                                    ossClient.putObject(bucketName, key, f);
                                } catch (Exception e1) {
   
                                    try {
   
                                        ossClient.putObject(bucketName, key, f);
                                    } catch (Exception e2) {
   
                                        logger.warn("file not exist on OSS and upload fail:{}|{}|{}", bucketName, key, f.getAbsolutePath());
                                        r = false;
                                        break;
                                    }
                                }
                            }
                        }
                    } else {
    //不检查是否已在OSS存在,直接上传
                        try {
   
                            ossClient.putObject(bucketName, key, f);
                        } catch (Exception e) {
   
                            try {
   
                                ossClient.putObject(bucketName, key, f);
                            } catch (Exception e1) {
   
                                try {
   
                                    ossClient.putObject(bucketName, key, f);
                                } catch (Exception e2) {
   
                                    logger.warn("OSS upload fail:{}|{}|{}", bucketName, key, f.getAbsolutePath());
                                    r = false;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
        return r;
    }

    @Override
    public void switchCredentials(Credentials creds) {
   
        ossClient.switchCredentials(creds);
    }

    @Override
    public void shutdown() {
   
        /*
         * do nothing, this method should make no effect.
         */
    }

    @Override
    public Bucket createBucket(String bucketName) throws OSSException, ClientException {
   
        return ossClient.createBucket(bucketName);
    }

    @Override
    public Bucket createBucket(CreateBucketRequest createBucketRequest) throws OSSException, ClientException {
   
        return ossClient.createBucket(createBucketRequest);
    }

    @Override
    public void deleteBucket(String bucketName) throws OSSException, ClientException {
   
        ossClient.deleteBucket(bucketName);
    }

    @Override
    public void deleteBucket(GenericRequest genericRequest) throws OSSException, ClientException {
   
        ossClient.deleteBucket(genericRequest);
    }

    @Override
    public List<Bucket> listBuckets() throws OSSException, ClientException {
   
        return ossClient.listBuckets();
    }

    @Override
    public BucketList listBuckets(String prefix, String marker, Integer maxKeys) throws OSSException, ClientException {
   
        return ossClient.listBuckets(prefix, marker, maxKeys);
    }

    @Override
    public BucketList listBuckets(ListBucketsRequest listBucketsRe
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值