调用阿里云的对象存储,附工具类

一、前言

最近项目要用到阿里云的oss,这里做个记录。

二、准备

先购买阿里云的对象存储

在这里插入图片描述

然后根据这里的指引创建bucket,绑定域名

在这里插入图片描述

这里已经创建好了

在这里插入图片描述

点击已经创建好的bucket,在这里绑定域名

在这里插入图片描述
在这里插入图片描述

这里已经绑定好了

其实不绑定也可以,阿里云会提供默认的域名,但是这样访问文件的时候就是下载,不能在线预览

如何在这里拿到阿里云的 AccessKey 配置访问凭证

在这里插入图片描述

三、对接

在上面页面拉到最下面

在这里插入图片描述

文档中心链接

因为用的是Java8.引用的是这个依赖

在这里插入图片描述

<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.17.4</version>
</dependency>

这里可以看到其他依赖,这是我引用的依赖

<!-- https://mvnrepository.com/artifact/com.aliyun.oss/aliyun-sdk-oss -->
<!--阿里云oss相关依赖-->
<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.18.1</version>
</dependency>

因为这边需要在项目中对文件进行上传和访问,所以调试的是这一部分

在这里插入图片描述

这里准备了一张图片

在这里插入图片描述

下面是演示,完整代码在 四、工具类 中

1、上传文件

在这里插入图片描述

2、查询文件

在这里插入图片描述

将链接放浏览器

在这里插入图片描述

3、下载文件

在这里插入图片描述

到对应目录看下

在这里插入图片描述

可以看到已经下载下来了

4、列出文件

在这里插入图片描述

5、删除文件

在这里插入图片描述

四、工具类

1、配置类

package com.zsp.demo.aliyun.dto;

import lombok.Data;

/**
 * 阿里云公共请求参数
 *
 * @author:user
 * @date: 2022-09-05 10:38
 */
@Data
public class AliyunConfig {
    //阿里云accessKeyId
    private String accessKeyId;

    //阿里云accessSecret
    private String accessSecret;

    //阿里云识别身份证的regionId,设置请求参数的方法有横线,似乎废弃了
    private String regionId;

    //阿里云三要素核验授权码。
    private String AuthCode;

    /*
    阿里云的 Security Token
        目前三要素核验必填
     */
    private String securityToken;

    /*
    阿里云的 type
        目前三要素核验中用到,为空表示AK&SK初始化,传入“sts”表示STS鉴权方式初始化(建议)
     */
    private String type;

    /*
    阿里云的 endpoint
     */
    private String endpoint;
}

2、请求参数

package com.zsp.demo.aliyun.oss.dto;

import lombok.Data;

import java.io.File;
import java.io.InputStream;

/**
 * 阿里云os请求参数
 *
 * @author: gan
 * @date: 2025-04-28 14:35
 */
@Data
public class OSSParam {

    /**
     * bucket名称
     */
    private String bucketName;

    /**
     * 对象名称
     */
    private String objectName;

    /**
     * 文件流
     */
    private InputStream inputStream;

    /**
     * 文件
     */
    private File file;

    /**
     * 文件下载路径
     *
     * 本地文件的完整地址,比如下载文件在oss中桶为 oss-cn-shenzhen-aliyuncs-com ,路径为 dev/test/cat.jpg
     * 要将其下载到本地的目录 /tmp/aliyun/oss ,此时值为:/tmp/aliyun/oss
     */
    private String downloadPath;
}

3、工具类

package com.zsp.demo.aliyun.oss.utils;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.LoggerContext;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.*;
import com.zsp.demo.aliyun.dto.AliyunConfig;
import com.zsp.demo.aliyun.oss.dto.OSSParam;
import com.zsp.demo.utils.VerifyUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.List;

/**
 * 阿里云OSS
 *
 * @author: gan
 * @date: 2025-04-28 14:32
 */
public class AliyunOSSUtil {

    private static final Logger log = LoggerFactory.getLogger(AliyunOSSUtil.class);

    /**
     * 这部分静态代码块用来降低 org.apache.http 包的日志级别,调试时可以将其注释
     */
    static {
        // 获取 Logback 的 LoggerContext
        LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
        // 设置 org.apache.http 包的日志级别为 WARN
        loggerContext.getLogger("org.apache.http").setLevel(Level.WARN);
        // 可选:关闭 HTTP 请求/响应的详细日志(Wire Log)
        loggerContext.getLogger("org.apache.http.wire").setLevel(Level.ERROR);
    }

    public static void main(String[] args) throws Exception{
        AliyunConfig config = new AliyunConfig();
        config.setAccessKeyId("你的阿里云AccessKeyId");
        config.setAccessSecret("你的阿里云AccessSecret");

        /**
         * 这个两个参数可以更加 bucket 所在地域查询如下链接:
         * https://help.aliyun.com/zh/oss/user-guide/regions-and-endpoints?spm=a2c4g.11186623.help-menu-31815.d_4_0_0.ca056bd2JutCyw
         */
        config.setEndpoint("https://oss-cn-wuhan-lr.aliyuncs.com");
        config.setRegionId("cn-wuhan-lr");

//        //============================上传文件 接口测试================================
//        String fileUrl = "/tmp/images/cat.jpg";  //本地文件地址
//        File file = new File(fileUrl);
//
//        OSSParam putParam = new OSSParam();
//        putParam.setBucketName("bucketname");
//        putParam.setObjectName("dev/test/cat.jpg");  //阿里云 oss bucket下的文件地址,文件名相同时会覆盖
//
//        //方式一:通过文件流方式
//        putParam.setInputStream(new FileInputStream(file));
//
//        //方式二:通过文件方式
//        //putParam.setFile(file);
//
//        AliyunOSSUtil.putObject(config, putParam);

//        //============================下载文件 接口测试================================
//        OSSParam getObjectParam = new OSSParam();
//        getObjectParam.setBucketName("bucketname");
//        getObjectParam.setObjectName("dev/test/cat.jpg");  //阿里云 oss bucket下的文件地址,文件名相同时会覆盖
//        getObjectParam.setDownloadPath("/opt/images");  //本地文件目录
//
//        String downloadFilePath = AliyunOSSUtil.getObject(config, getObjectParam);
//        System.out.println("downloadFilePath:" + downloadFilePath);

//        //============================列出文件 接口测试================================
//        OSSParam listObjectParam = new OSSParam();
//        listObjectParam.setBucketName("bucketname");
//        listObjectParam.setObjectName("dev");  //不传只返回桶下面的第一个文件夹下的所有文件,传了时如果当前目录存在多个文件夹,也只查询第一个文件夹下的所有文件
//
//        List<OSSObjectSummary> ossObjectSummarieList = AliyunOSSUtil.listObjects(config, listObjectParam);
//        for (OSSObjectSummary ossObjectSummary : ossObjectSummarieList) {
//            System.out.println(JSONObject.toJSONString(ossObjectSummary, true));
//        }

//        //============================删除文件 接口测试================================
//        OSSParam deleteObjectParam = new OSSParam();
//        deleteObjectParam.setBucketName("bucketname");
//        deleteObjectParam.setObjectName("dev/test/cat.jpg");  //不传只返回桶下面的第一个文件夹下的所有文件,传了时如果当前目录存在多个文件夹,也只查询第一个文件夹下的所有文件
//
//        AliyunOSSUtil.deleteObject(config, deleteObjectParam);

//        //============================查询文件 接口测试================================
//
//        OSSParam getUrlParam = new OSSParam();
//        getUrlParam.setBucketName("bucketname");
//        getUrlParam.setObjectName("dev/test/cat.jpg");
//
//        //这里的endpoint要使用自定义域名才行,不然放浏览器访问是直接下载
//        config.setEndpoint("https://test.com");
//
//        String url = AliyunOSSUtil.getUrl(config, getUrlParam);
//        System.out.println("url:" + url);
    }

    /**
     * 获取阿里云OSS对象
     *
     * @param config  阿里云配置
     * @return
     */
    private static OSS getOSS(AliyunConfig config) {
        DefaultCredentialProvider credentialsProvider = new DefaultCredentialProvider(config.getAccessKeyId(), config.getAccessSecret());

        return OSSClientBuilder.create()
                .endpoint(config.getEndpoint())
                .credentialsProvider(credentialsProvider)
                .region(config.getRegionId())
                .build();
    }

    /**
     * 上传文件
     *
     * @param config  阿里云配置
     * @param param  请求参数
     */
    public static void putObject(AliyunConfig config, OSSParam param) {
        String bucketName = null;
        String objectName = null;
        InputStream inputStream = null;
        File file = null;

        OSS oss = null;
        PutObjectResult putObjectResult = null;
        try {
            oss = getOSS(config);

            inputStream = param.getInputStream();
            file = param.getFile();
            bucketName = param.getBucketName();
            objectName = param.getObjectName();

            if (VerifyUtil.isNotEmpty(inputStream)) {
                putObjectResult = oss.putObject(bucketName, objectName, inputStream);
            } else if (VerifyUtil.isNotEmpty(file)) {
                putObjectResult = oss.putObject(bucketName, objectName, file);
            } else {
                throw new RuntimeException("文件流和文件上传其一!");
            }

            //没有报错就是上传成功
            log.info("上传成功! bucket 名称为 {} , 文件名称为 {}",  bucketName, objectName);
        } catch (Exception e) {

            throw new RuntimeException(e);
        } finally {
            if (VerifyUtil.isNotEmpty(inputStream)) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }

            if (VerifyUtil.isNotEmpty(oss)) {
                oss.shutdown();
            }
        }

    }

    /**
     * 下载文件
     *
     * @param config  阿里云配置
     * @param param  请求参数
     * @return  下载文件路径
     */
    public static String getObject(AliyunConfig config, OSSParam param) {
        String bucketName = null;
        String objectName = null;
        String downloadPath = null;
        String downloadFilePath = null;  //下载文件路径

        OSS oss = null;
        InputStream contentStream = null;
        FileOutputStream downloadOutputStream = null;
        try {
            oss = getOSS(config);

            bucketName = param.getBucketName();
            objectName = param.getObjectName();
            downloadPath = param.getDownloadPath();

            OSSObject object = oss.getObject(bucketName, objectName);

            contentStream = object.getObjectContent();

            if (VerifyUtil.isEmpty(downloadPath)) {
                downloadPath = "/tmp/aliyun/oss";  //默认路径
            }

            //创建下载文件夹路径,防止文件夹不存在
            Files.createDirectories(Paths.get(downloadPath));

            String[] objectNameArr = objectName.split("/");  //切分对象名称后的数组
            downloadFilePath = downloadPath + File.separator + objectNameArr[objectNameArr.length - 1];  //最后一个就是文件名,包含后缀

            byte[] buffer = new byte[1024];
            int bufferNum = 0;
            downloadOutputStream = new FileOutputStream(downloadFilePath);
            while ((bufferNum = contentStream.read(buffer)) != -1) {
                downloadOutputStream.write(buffer, 0, bufferNum);
            }

            //没有报错就是下载成功
            log.info("下载成功! bucket 名称为 {} , 文件名称为 {}",  bucketName, objectName);

            return downloadFilePath;
        } catch (Exception e) {

            throw new RuntimeException(e);
        } finally {
            if (VerifyUtil.isNotEmpty(contentStream)) {
                try {
                    contentStream.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }

            if (VerifyUtil.isNotEmpty(downloadOutputStream)) {
                try {
                    downloadOutputStream.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }

            if (VerifyUtil.isNotEmpty(oss)) {
                oss.shutdown();
            }
        }
    }

    /**
     * 列出文件
     *
     * @param config  阿里云配置
     * @param param  请求参数
     * @return  List<OSSObjectSummary>  文件信息集合
     */
    public static List<OSSObjectSummary> listObjects(AliyunConfig config, OSSParam param) {
        String bucketName = null;
        String objectName = null;

        OSS oss = null;
        try {
            oss = getOSS(config);

            bucketName = param.getBucketName();
            objectName = param.getObjectName();

            ListObjectsV2Result listObjectsV2Result = oss.listObjectsV2(bucketName, objectName);
            List<OSSObjectSummary> objectSummaries = listObjectsV2Result.getObjectSummaries();
//            for (OSSObjectSummary objectSummary : objectSummaries) {
//                //完整信息打印
//                //log.info("bucketName {} , key {} , eTag {} , size {} , lastModified {} , storageClass {} , owner {} , type {} , restoreInfo {}", objectSummary.getBucketName(), objectSummary.getKey(), objectSummary.getETag(), objectSummary.getSize(), objectSummary.getLastModified(), objectSummary.getStorageClass(), objectSummary.getOwner(), objectSummary.getType(), objectSummary.getRestoreInfo());
//
//                //部分信息打印
//                log.info("bucketName {} , key {} , size {} , lastModified {} ", objectSummary.getBucketName(), objectSummary.getKey(), objectSummary.getSize(), objectSummary.getLastModified());
//            }

            return objectSummaries;
        } catch (Exception e) {

            throw new RuntimeException(e);
        } finally {
            if (VerifyUtil.isNotEmpty(oss)) {
                oss.shutdown();
            }
        }
    }

    /**
     * 删除文件
     *
     * @param config  阿里云配置
     * @param param  请求参数
     */
    public static void deleteObject(AliyunConfig config, OSSParam param) {
        String bucketName = null;
        String objectName = null;

        OSS oss = null;
        try {
            oss = getOSS(config);

            bucketName = param.getBucketName();
            objectName = param.getObjectName();

            VoidResult voidResult = oss.deleteObject(bucketName, objectName);  //不报错就是删除成功,文件不存在也不会报错
            //log.info("requestId {}", voidResult.getRequestId());
            log.info("删除成功! bucket 名称为 {} , 文件名称为 {}",  bucketName, objectName);
        } catch (Exception e) {

            throw new RuntimeException(e);
        } finally {
            if (VerifyUtil.isNotEmpty(oss)) {
                oss.shutdown();
            }
        }
    }

    /**
     * 查询文件链接
     *
     * @param config  阿里云配置
     * @param param  请求参数
     */
    public static String getUrl(AliyunConfig config, OSSParam param) {
        CredentialsProvider credentialsProvider = new DefaultCredentialProvider(config.getAccessKeyId(), config.getAccessSecret());

        credentialsProvider.setCredentials(new DefaultCredentials(config.getAccessKeyId(), config.getAccessSecret()));

        // 创建OSSClient实例。
        // 当OSSClient实例不再使用时,调用shutdown方法以释放资源。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);

        // 请注意,设置true开启CNAME选项
        clientBuilderConfiguration.setSupportCname(true);

        OSS ossClient = OSSClientBuilder.create()
                .endpoint(config.getEndpoint())
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(config.getRegionId())
                .build();

        String resultUrl = null;
        try {
            // 设置预签名URL过期时间,单位为毫秒。本示例以设置过期时间为1小时为例。
            Date expiration = new Date(new Date().getTime() + 3600 * 1000L);

            // 生成预签名URL。
            GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(param.getBucketName(), param.getObjectName(), HttpMethod.GET);

            // 设置过期时间。
            request.setExpiration(expiration);

            // 通过HTTP GET请求生成预签名URL。
            URL url = ossClient.generatePresignedUrl(request);

            if (null != url) {
                resultUrl = url.toString();
            }
        } catch (OSSException oe) {
            log.error("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            log.error("Error Message: {}" + oe.getErrorMessage());
            log.error("Error Code: {}" + oe.getErrorCode());
            log.error("Request ID: {}" + oe.getRequestId());
            log.error("Host ID: {}" + oe.getHostId());
        } catch (ClientException ce) {
            log.error("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            log.error("Error Message: {}" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }

            return resultUrl;
        }
    }

}

posted @ 2025-10-24 15:17  Percep_gan  阅读(27)  评论(0)    收藏  举报  来源