阿里云OSS简单使用

2,099 阅读5分钟
简单记录java操作OSS上传、下载、预览、获取token。

第一步

提前注册好阿里云的账号。进入OSS的管理控制台,生成Access key。

第二步

点击进入,创建AccesskeyID和AccesskeySecret。

第三步

创建bucketName,可以在控制台,也可以在代码中创建。我是直接在控制台创建的(偷懒嘛!哈哈)

创建bucketName时选择上传服务器区域,得到的Endpoint也是后面要用到的。

代码中创建的话

// Endpoint以杭州为例,其它Region请按实际情况填写。
String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
String accessKeyId = "<yourAccessKeyId>";
String accessKeySecret = "<yourAccessKeySecret>";

// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

// 创建CreateBucketRequest对象。
CreateBucketRequest createBucketRequest = new CreateBucketRequest("<yourBucketName>");

// 如果创建存储空间的同时需要指定存储类型以及数据容灾类型, 可以参考以下代码。
// 此处以设置存储空间的存储类型为标准存储为例。
// createBucketRequest.setStorageClass(StorageClass.Standard);
// 默认情况下,数据容灾类型为本地冗余存储,即DataRedundancyType.LRS。如果需要设置数据容灾类型为同城冗余存储,请替换为DataRedundancyType.ZRS。
// createBucketRequest.setDataRedundancyType(DataRedundancyType.ZRS)
// 判断bucketName是否存在
boolean exists = ossClient.doesBucketExist("<yourBucketName>");
if(!exists) {
    // 创建存储空间。
    ossClient.createBucket(createBucketRequest);
} else {
    // 返回存在此存储空间
}
// 关闭OSSClient。
ossClient.shutdown();

到此需要的基本设置也都获取到了。上代码~

文件上传

配置我是放到了yml文件中

# 文件存储服务器
file:
  access-key: *********Bznv5j3EQZJACo
  secret-key: *********aLaIwn3aSmLyjkm
  default-bucket: *******-dev
  server-endpoint: http://oss-cn-hangzhou.aliyuncs.com
  sts-endpoint: sts.cn-hangzhou.aliyuncs.com
  expire-seconds: 3600
  role-arn: 'acs:ram::******630748301:role/*********-dev'
  role-session-name: *******_user
  policy: '{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}'

获取的

@Data
@Component
@ConfigurationProperties(prefix = "file")
public class FileProperties {

    /**
     * 默认的文件桶名称
     */
    private String defaultBucket;

    /**
     * 密钥的key
     */
    private String accessKey;

    /**
     * 密钥的钥匙
     */
    private String secretKey;

    /**
     * 文件服务器的url(全路径,例如:http://127.0.0.1:9000)
     */
    private String serverEndpoint;

    /**
     * STS服务的接入地址url(全路径,例如:sts.aliyuncs.com)
     */
    private String stsEndpoint;

    /**
     * 文件过期时间,默认:秒
     */
    private Integer expireSeconds;
    /**
     * 指定角色的ARN。格式:acs:ram::$accountID:role/$roleName 。
     */
    private String roleArn;
    /**
     * 用户自定义参数
     */
    private String roleSessionName;
    /**
     * 权限策略。
     */
    private String policy;

}

使用的时候直接注入

public String upload(String bucketName, String objectName, byte[] objectBytes) {
    OSS ossClient = createOssClient(bucketName);
    try {
        // 使用putObject上传一个文件到存储桶中
        ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(objectBytes));
        return objectName.substring(0,objectName.lastIndexOf("."));
    } catch (Exception e) {
        log.error("上传文件出错!", e);
        throw new ServiceException(FileExceptionEnum.FILE_UPLOAD_ERROR);
    } finally {
        ossClient.shutdown();
    }
}

private OSS createOssClient(String bucketName) {
    try {
        // 使用OSS服务的URL,端口,Access key和Secret key创建一个OSSClient对象
        OSS ossClient = new OSSClientBuilder().build(fileProperties.getServerEndpoint(), fileProperties.getAccessKey(), fileProperties.getSecretKey());
        // 检查存储桶是否已经存在,不存在就创建一个令牌桶
        boolean isExist = ossClient.doesBucketExist(bucketName);
        if (!isExist) {
            ossClient.createBucket(bucketName);
        }

        return ossClient;

    } catch (Exception e) {
        log.error("创建文件客户端错误!", e);
        throw new ServiceException(FileExceptionEnum.FILE_CLIENT_ERROR);
    }
}

文件下载

public String getDownloadUrl(String bucketName, String objectName, String fileName, Integer expireSeconds) {
    OSS ossClient = createOssClient(bucketName);
    try {
        OSSObject ossObject = ossClient.getObject(bucketName, objectName);
        BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent()));
        String line = "";
        while (true) {
            line = reader.readLine();
            if (line == null) break;
        }
        // 数据读取完成后,获取的流必须关闭,否则会造成连接泄漏,导致请求无连接可用,程序无法正常工作。
        reader.close();
        return line;
    } catch (Exception e) {
        log.error("获取文件流出错!", e);
        throw new ServiceException(FileExceptionEnum.FILE_IO_ERROR);
    } finally {
        ossClient.shutdown();
    }
}

文件预览

public String getPreviewUrl(String bucketName, String objectName) {
    // 创建OSSClient实例。
    OSS ossClient = createOssClient(bucketName);
    try {
        // 设置URL过期时间为1小时。
        Date expiration = new Date(new Date().getTime() + 3600 * 1000);
        // 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。
        URL url = ossClient.generatePresignedUrl(bucketName, objectName, expiration);
        return url.toString();
    } catch (Exception e) {
        log.error("获取文件下载url出错!", e);
        throw new ServiceException(FileExceptionEnum.FILE_GET_URL_ERROR);
    } finally {
        ossClient.shutdown();
    }
}

获取STS

什么是STS?

阿里云临时安全令牌(Security Token Service,STS)是阿里云提供的一种临时访问权限管理服务。

功能特性 通过STS服务,您所授权的身份主体(RAM用户或RAM角色)可以获取一个自定义时效和访问权限的临时访问令牌。STS令牌持有者可以通过以下方式访问阿里云资源:

通过编程方式访问被授权的阿里云服务API。 登录阿里云控制台操作被授权的云资源。

需要在项目pom文件中添加依赖。

<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-sts</artifactId>
    <version>3.0.0</version>
</dependency>
<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-core</artifactId>
    <version>4.4.6</version>
</dependency>
public AssumeRoleResponse getSecurityToken() {
    try {
        //构造default profile(参数留空,无需添加Region ID)
        IClientProfile profile = DefaultProfile.getProfile("", fileProperties.getAccessKey(), fileProperties.getSecretKey());
        //用profile构造client
        DefaultAcsClient client = new DefaultAcsClient(profile);
        final AssumeRoleRequest request = new AssumeRoleRequest();
        request.setSysEndpoint(fileProperties.getStsEndpoint());
        request.setSysMethod(MethodType.POST);
        request.setRoleArn(fileProperties.getRoleArn());
        request.setRoleSessionName(fileProperties.getRoleSessionName());
        request.setPolicy(fileProperties.getPolicy()); // Optional
        final AssumeRoleResponse response = client.getAcsResponse(request);
        System.out.println("Expiration: " + response.getCredentials().getExpiration());
        System.out.println("Access Key Id: " + response.getCredentials().getAccessKeyId());
        System.out.println("Access Key Secret: " + response.getCredentials().getAccessKeySecret());
        System.out.println("Security Token: " + response.getCredentials().getSecurityToken());
        System.out.println("RequestId: " + response.getRequestId());
        return response;
    } catch (ClientException e) {
        System.out.println("Failed:");
        System.out.println("Error code: " + e.getErrCode());
        System.out.println("Error message: " + e.getErrMsg());
        System.out.println("RequestId: " + e.getRequestId());
        throw new ServiceException(FileExceptionEnum.FILE_GET_TOKEN_ERROR);
    }
}
名称 类型 是否必选 示例值 描述
Action String AssumeRole 要执行的操作。取值:AssumeRole
RoleArn String acs:ram::123456789012****:role/adminrole 指定角色的ARN。格式:acs:ram::accountID:role/roleName accountID:阿里云账号ID。您可以通过登录阿里云控制台,将鼠标悬停在右上角头像的位置,单击安全设置进行查看。roleName:RAM角色名称。您可以通过登录RAM控制台,单击左侧导航栏的RAM角色管理,在RAM角色名称列表下进行查看。
RoleSessionName String alice 用户自定义参数。此参数用来区分不同的令牌,可用于用户级别的访问审计。长度为2~32个字符,可包含英文字母、数字、点号(.)、at(@)、短横线(-)和下划线(_)
Policy String {"Statement": [{"Action": [""],"Effect": "Allow","Resource": [""]}],"Version":"1"} 生成STSToken时可以指定一个额外的权限策略,以进一步限制STSToken的权限。若不指定则返回的Token拥有指定角色的所有权限。长度为1~1024个字符。
DurationSeconds String 3600 过期时间,单位为秒。过期时间最小值为900秒,最大值为MaxSessionDuration设置的时间。默认值为3600秒。

至此Demo记录完毕!