本文介绍如何使用STS以及签名URL临时授权访问OSS资源。

说明 由于STS临时账号以及签名URL均需设置有效时长,当您使用STS临时账号生成签名URL执行相关操作(例如上传、下载文件)时,以最小的有效时长为准。例如您的STS临时账号的有效时长设置为1200秒、签名URL设置为3600秒时,当有效时长超过1200秒后,您无法使用此STS临时账号生成的签名URL上传文件。

使用STS进行临时授权

OSS可以通过阿里云STS(Security Token Service)进行临时授权访问。阿里云STS是为云计算用户提供临时访问令牌的Web服务。通过STS,您可以为第三方应用或子用户(即用户身份由您自己管理的用户)颁发一个自定义时效和权限的访问凭证。关于STS的更多信息,请参见STS介绍

STS的优势如下:

  • 您无需透露您的长期密钥(AccessKey)给第三方应用,只需生成一个访问令牌并将令牌交给第三方应用。您可以自定义这个令牌的访问权限及有效期限。
  • 您无需关心权限撤销问题,访问令牌过期后自动失效。

通过STS临时授权访问OSS的步骤如下:

  1. 获取临时访问凭证

    临时访问凭证包括临时访问密钥(AccessKey ID和AccessKey Secret)和安全令牌(SecurityToken)。临时访问凭证有效时间单位为秒,最小值为900,最大值以当前角色设定的最大会话时间为准。更多信息,请参见设置角色最大会话时间

    您可以通过以下两种方式获取临时访问凭证。

    • 方式一

      通过调用STS服务的AssumeRole接口获取临时访问凭证。

    • 方式二

      通过各语言STS SDK获取临时访问凭证。

  2. 使用STS临时授权上传和下载文件。
    import com.aliyun.oss.*;
    import com.aliyun.oss.model.GetObjectRequest;
    import com.aliyun.oss.model.PutObjectRequest;
    import java.io.File;
    
    public class Demo {
        public static void main(String[] args) throws Throwable {
            // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
            String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
            // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
            String accessKeyId = "yourAccessKeyId";
            String accessKeySecret = "yourAccessKeySecret";
            // 从STS服务获取的安全令牌(SecurityToken)。
            String securityToken = "yourSecurityToken";
            // 填写Bucket名称,例如examplebucket。
            //String bucketName = "examplebucket";
            // 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。
            //String objectName = "exampleobject.txt";
            //String pathName = "D:\\localpath\\examplefile.txt";
    
            // 从STS服务获取临时访问凭证后,您可以通过临时访问密钥和安全令牌生成OSSClient。
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);
    
            try {
                // 执行OSS相关操作,例如上传、下载文件等。
                // 上传文件,此处以上传本地文件为例介绍。
                // 填写本地文件的完整路径。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件。
                //PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new File(pathName));
                //ossClient.putObject(putObjectRequest);
    
                // 下载OSS文件到本地文件。如果指定的本地文件存在则覆盖,不存在则新建。
                // 如果未指定本地路径,则下载后的文件默认保存到示例程序所属项目对应本地路径中。
                //ossClient.getObject(new GetObjectRequest(bucketName, objectName), new File(pathName));
            } catch (OSSException oe) {
                System.out.println("Caught an OSSException, which means your request made it to OSS, "
                        + "but was rejected with an error response for some reason.");
                System.out.println("Error Message:" + oe.getErrorMessage());
                System.out.println("Error Code:" + oe.getErrorCode());
                System.out.println("Request ID:" + oe.getRequestId());
                System.out.println("Host ID:" + oe.getHostId());
            } catch (ClientException ce) {
                System.out.println("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.");
                System.out.println("Error Message:" + ce.getMessage());
            } finally {
                if (ossClient != null) {
                    ossClient.shutdown();
                }
            }
        }
    }

使用签名URL进行临时授权

以下介绍使用签名URL临时授权的常见示例。

说明 如果需要生成HTTPS协议的签名URL,请将Endpoint中的通信协议设置为HTTPS。

生成签名URL

您可以将生成的签名URL提供给访客进行临时访问。生成签名URL时,您可以自定义URL的过期时间来限制访客的访问时长。

注意 通过以下示例生成的签名URL中如果包含特殊符号+,可能出现无法正常访问该签名URL的现象。如需正常访问该签名URL,请将签名URL中的+替换为%2B

生成以GET方法访问的签名URL

您可以根据需要一次生成单个或者多个以GET方法访问的签名URL。

  • 生成单个以GET方法访问的签名URL

    以下代码用于一次生成单个以GET方法访问的签名URL。

    import com.aliyun.oss.*;
    import java.net.URL;
    import java.util.Date;
    
    public class Demo {
        public static void main(String[] args) throws Throwable {
            // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
            String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
            // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
            String accessKeyId = "yourAccessKeyId";
            String accessKeySecret = "yourAccessKeySecret";
            // 从STS服务获取的安全令牌(SecurityToken)。
            String securityToken = "yourSecurityToken";
            // 填写Bucket名称,例如examplebucket。
            String bucketName = "examplebucket";
            // 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。
            String objectName = "exampleobject.txt";
    
            // 从STS服务获取临时访问凭证后,您可以通过临时访问密钥和安全令牌生成OSSClient。
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);
    
            try {
                // 设置签名URL过期时间,单位为毫秒。
                Date expiration = new Date(new Date().getTime() + 3600 * 1000);
                // 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。
                URL url = ossClient.generatePresignedUrl(bucketName, objectName, expiration);
                System.out.println(url);
            } catch (OSSException oe) {
                System.out.println("Caught an OSSException, which means your request made it to OSS, "
                        + "but was rejected with an error response for some reason.");
                System.out.println("Error Message:" + oe.getErrorMessage());
                System.out.println("Error Code:" + oe.getErrorCode());
                System.out.println("Request ID:" + oe.getRequestId());
                System.out.println("Host ID:" + oe.getHostId());
            } catch (ClientException ce) {
                System.out.println("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.");
                System.out.println("Error Message:" + ce.getMessage());
            } finally {
                if (ossClient != null) {
                    ossClient.shutdown();
                }
            }
        }
    }                   
  • 生成多个以GET方法访问的签名URL

    以下代码用于一次生成多个以GET方法访问的签名URL。

    import com.aliyun.oss.*;
    import java.net.URL;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    
    public class Demo {
        public static void main(String[] args) throws Throwable {
            // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
            String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
            // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
            String accessKeyId = "yourAccessKeyId";
            String accessKeySecret = "yourAccessKeySecret";
            // 从STS服务获取的安全令牌(SecurityToken)。
            String securityToken = "yourSecurityToken";
            // 填写Bucket名称,例如examplebucket。
            String bucketName = "examplebucket";
            // 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。
            // 此处请填写多个Object完整路径,用于一次性获取多个Object的签名URL。
            String objectNameList [] = {"exampleobject.txt","exampleimage.jpg"};
    
            // 从STS服务获取临时访问凭证后,您可以通过临时访问密钥和安全令牌生成OSSClient。
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);
    
            try {
                // 设置签名URL过期时间,单位为毫秒。
                Date expiration = new Date(new Date().getTime() + 3600 * 1000);
    
                List<URL> urlList = new ArrayList<URL>();
                for(int i=0; i<objectNameList.length; i++){
                    URL url = ossClient.generatePresignedUrl(bucketName, objectNameList[i], expiration);
                    urlList.add(url);
                }
                // 打印签名URL。
                for(URL url:urlList){
                    System.out.println(url);
                }
            } catch (OSSException oe) {
                System.out.println("Caught an OSSException, which means your request made it to OSS, "
                        + "but was rejected with an error response for some reason.");
                System.out.println("Error Message:" + oe.getErrorMessage());
                System.out.println("Error Code:" + oe.getErrorCode());
                System.out.println("Request ID:" + oe.getRequestId());
                System.out.println("Host ID:" + oe.getHostId());
            } catch (ClientException ce) {
                System.out.println("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.");
                System.out.println("Error Message:" + ce.getMessage());
            } finally {
                if (ossClient != null) {
                    ossClient.shutdown();
                }
            }
        }
    }

生成以其他HTTP方法访问的签名URL

如果您要授权其他用户临时执行其他操作(例如上传、删除文件等),需要生成对应的签名URL,例如生成以PUT方法访问的签名URL来上传文件。您可以根据需要一次生成单个或者多个以其他HTTP方法访问的签名URL。

  • 生成单个以其他HTTP方法访问的签名URL

    以下代码用于一次生成单个以其他HTTP方法访问的签名URL。

    import com.aliyun.oss.*;
    import com.aliyun.oss.common.utils.HttpHeaders;
    import com.aliyun.oss.model.GeneratePresignedUrlRequest;
    import java.io.ByteArrayInputStream;
    import java.net.URL;
    import java.util.*;
    
    import static com.aliyun.oss.internal.OSSHeaders.OSS_USER_METADATA_PREFIX;
    
    public class Demo {
        public static void main(String[] args) throws Throwable {
            // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
            String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
            // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
            String accessKeyId = "yourAccessKeyId";
            String accessKeySecret = "yourAccessKeySecret";
            // 从STS服务获取的安全令牌(SecurityToken)。
            String securityToken = "yourSecurityToken";
            // 填写Bucket名称,例如examplebucket。
            String bucketName = "examplebucket";
            // 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。
            String objectName = "exampleobject.txt";
    
            // 从STS服务获取临时访问凭证后,您可以通过临时访问密钥和安全令牌生成OSSClient。
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);
    
            try {
                GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectName, HttpMethod.PUT);
                // 设置签名URL过期时间,单位为毫秒。
                Date expiration = new Date(new Date().getTime() + 3600 * 1000);
                request.setExpiration(expiration);
                // 设置ContentType。
                request.setContentType("text/plain");
                // 设置自定义元信息。
                request.addUserMetadata("author", "aliy");
    
                // 生成签名URL。
                URL signedUrl = ossClient.generatePresignedUrl(request);
                System.out.println(signedUrl);
    
                Map<String, String> requestHeaders = new HashMap<String, String>();
                // 设置ContentType,必须和生成签名URL时设置的ContentType一致。
                requestHeaders.put(HttpHeaders.CONTENT_TYPE, "text/plain");
                // 设置自定义元信息。
                requestHeaders.put(OSS_USER_METADATA_PREFIX + "author", "aliy");
    
                // 使用签名URL上传文件。
                ossClient.putObject(signedUrl, new ByteArrayInputStream("Hello OSS".getBytes()), -1, requestHeaders, true);
            } catch (OSSException oe) {
                System.out.println("Caught an OSSException, which means your request made it to OSS, "
                        + "but was rejected with an error response for some reason.");
                System.out.println("Error Message:" + oe.getErrorMessage());
                System.out.println("Error Code:" + oe.getErrorCode());
                System.out.println("Request ID:" + oe.getRequestId());
                System.out.println("Host ID:" + oe.getHostId());
            } catch (ClientException ce) {
                System.out.println("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.");
                System.out.println("Error Message:" + ce.getMessage());
            } finally {
                if (ossClient != null) {
                    ossClient.shutdown();
                }
            }
        }
    }      
  • 生成多个以其他HTTP方法访问的签名URL

    以下代码用于一次生成多个以其他HTTP方法访问的签名URL。

    import com.aliyun.oss.*;
    import com.aliyun.oss.common.utils.HttpHeaders;
    import com.aliyun.oss.model.GeneratePresignedUrlRequest;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.net.URL;
    import java.util.*;
    import static com.aliyun.oss.internal.OSSConstants.DEFAULT_OBJECT_CONTENT_TYPE;
    import static com.aliyun.oss.internal.OSSHeaders.OSS_USER_METADATA_PREFIX;
    
    public class Demo {
        public static void main(String[] args) throws Throwable {
            // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
            String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
            // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
            String accessKeyId = "yourAccessKeyId";
            String accessKeySecret = "yourAccessKeySecret";
            // 从STS服务获取的安全令牌(SecurityToken)。
            String securityToken = "yourSecurityToken";
            // 填写Bucket名称,例如examplebucket。
            String bucketName = "examplebucket";
            // 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。
            // 此处请填写多个Object完整路径,用于一次性获取多个Object的签名URL。
            String objectNameList [] = {"exampleobject.txt","exampleimage.jpg"};
            String upLoadNameArray [] = {"D:\\localpath\\examplefile1.txt","D:\\localpath\\examplefile2.jpg"};
    
            // 从STS服务获取临时访问凭证后,您可以通过临时访问密钥和安全令牌生成OSSClient。
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);
    
            try {
                // 设置签名URL过期时间,单位为毫秒。
                Date expiration = new Date(new Date().getTime() + 3600 * 1000);
                for(int i=0; i<objectNameList.length; i++){
                    GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectNameList[i], HttpMethod.PUT);
                    request.setExpiration(expiration);
                    // 设置ContentType。
                    request.setContentType(DEFAULT_OBJECT_CONTENT_TYPE);
                    // 设置自定义元信息。
                    request.addUserMetadata("author", "aliy");
    
                    // 生成签名URL。
                    URL signedUrl = ossClient.generatePresignedUrl(request);
                    // 打印签名URL。
                    System.out.println(signedUrl);
    
                    Map<String, String> requestHeaders = new HashMap<String, String>();
                    requestHeaders.put(HttpHeaders.CONTENT_TYPE, DEFAULT_OBJECT_CONTENT_TYPE);
                    requestHeaders.put(OSS_USER_METADATA_PREFIX + "author", "aliy");
    
                    // 如果要上传字符串,请使用如下方式。
                    //ossClient.putObject(signedUrl, new ByteArrayInputStream("Hello OSS".getBytes()), -1, requestHeaders, true);
    
                    // 使用签名URL上传文件。
                    try {
                        ossClient.putObject(signedUrl, new FileInputStream(new File(upLoadNameArray[i])), -1, requestHeaders, true);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                }
            } catch (OSSException oe) {
                System.out.println("Caught an OSSException, which means your request made it to OSS, "
                        + "but was rejected with an error response for some reason.");
                System.out.println("Error Message:" + oe.getErrorMessage());
                System.out.println("Error Code:" + oe.getErrorCode());
                System.out.println("Request ID:" + oe.getRequestId());
                System.out.println("Host ID:" + oe.getHostId());
            } catch (ClientException ce) {
                System.out.println("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.");
                System.out.println("Error Message:" + ce.getMessage());
            } finally {
                if (ossClient != null) {
                    ossClient.shutdown();
                }
            }
        }
    }

通过传入HttpMethod.PUT参数,访客可以使用生成的签名URL上传文件。

生成带有指定参数的签名URL

您可以根据需要一次生成单个或者多个带有指定参数的签名URL。

  • 生成单个带有指定参数的签名URL

    以下代码用于一次生成单个带有指定参数的签名URL。

    import com.aliyun.oss.*;
    import com.aliyun.oss.model.GeneratePresignedUrlRequest;
    import java.net.URL;
    import java.util.*;
    
    public class Demo {
        public static void main(String[] args) throws Throwable {
            // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
            String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
            // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
            String accessKeyId = "yourAccessKeyId";
            String accessKeySecret = "yourAccessKeySecret";
            // 从STS服务获取的安全令牌(SecurityToken)。
            String securityToken = "yourSecurityToken";
            // 填写Bucket名称,例如examplebucket。
            String bucketName = "examplebucket";
            // 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。
            String objectName = "exampleobject.txt";
    
            // 从STS服务获取临时访问凭证后,您可以通过临时访问密钥和安全令牌生成OSSClient。
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);
    
            try {
                // 创建请求。
                GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, objectName);
                // 设置HttpMethod为PUT。
                generatePresignedUrlRequest.setMethod(HttpMethod.PUT);
                // 添加用户自定义元信息。
                generatePresignedUrlRequest.addUserMetadata("author", "baymax");
                // 设置ContentType。
                generatePresignedUrlRequest.setContentType("application/txt");
                // 设置签名URL过期时间,单位为毫秒。
                Date expiration = new Date(new Date().getTime() + 3600 * 1000);
                generatePresignedUrlRequest.setExpiration(expiration);
                // 生成签名URL。
                URL url = ossClient.generatePresignedUrl(generatePresignedUrlRequest);
                System.out.println(url);
            } catch (OSSException oe) {
                System.out.println("Caught an OSSException, which means your request made it to OSS, "
                        + "but was rejected with an error response for some reason.");
                System.out.println("Error Message:" + oe.getErrorMessage());
                System.out.println("Error Code:" + oe.getErrorCode());
                System.out.println("Request ID:" + oe.getRequestId());
                System.out.println("Host ID:" + oe.getHostId());
            } catch (ClientException ce) {
                System.out.println("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.");
                System.out.println("Error Message:" + ce.getMessage());
            } finally {
                if (ossClient != null) {
                    ossClient.shutdown();
                }
            }
        }
    }
  • 生成多个带有指定参数的签名URL

    以下代码用于一次生成多个带有指定参数的签名URL。

    import com.aliyun.oss.*;
    import com.aliyun.oss.model.GeneratePresignedUrlRequest;
    import java.net.URL;
    import java.util.*;
    
    public class Demo {
        public static void main(String[] args) throws Throwable {
            // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
            String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
            // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
            String accessKeyId = "yourAccessKeyId";
            String accessKeySecret = "yourAccessKeySecret";
            // 从STS服务获取的安全令牌(SecurityToken)。
            String securityToken = "yourSecurityToken";
            // 填写Bucket名称,例如examplebucket。
            String bucketName = "examplebucket";
            // 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。
            // 此处请填写多个Object完整路径,用于一次性获取多个Object的签名URL。
            String objectNameList [] = {"exampleobject.txt","exampleimage.jpg"};
    
            // 从STS服务获取临时访问凭证后,您可以通过临时访问密钥和安全令牌生成OSSClient。
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);
    
            try {
                // 设置签名URL过期时间,单位为毫秒。
                Date expiration = new Date(new Date().getTime() + 3600 * 1000);
                for(int i=0; i<objectNameList.length; i++){
                    // 创建请求。
                    GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, objectNameList[i]);
                    // 设置HttpMethod为PUT。
                    generatePresignedUrlRequest.setMethod(HttpMethod.PUT);
                    // 添加用户自定义元信息。
                    generatePresignedUrlRequest.addUserMetadata("author", "baymax");
                    // 设置ContentType。
                    generatePresignedUrlRequest.setContentType("application/txt");
                    generatePresignedUrlRequest.setExpiration(expiration);
                    // 生成签名URL。
                    URL url = ossClient.generatePresignedUrl(generatePresignedUrlRequest);
                    // 打印签名URL。
                    System.out.println(url);
                }
            } catch (OSSException oe) {
                System.out.println("Caught an OSSException, which means your request made it to OSS, "
                        + "but was rejected with an error response for some reason.");
                System.out.println("Error Message:" + oe.getErrorMessage());
                System.out.println("Error Code:" + oe.getErrorCode());
                System.out.println("Request ID:" + oe.getRequestId());
                System.out.println("Host ID:" + oe.getHostId());
            } catch (ClientException ce) {
                System.out.println("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.");
                System.out.println("Error Message:" + ce.getMessage());
            } finally {
                if (ossClient != null) {
                    ossClient.shutdown();
                }
            }
        }
    }

使用签名URL上传或下载文件

  • 使用签名URL上传文件

    以下代码用于生成上传的签名URL,并使用签名URL上传文件。

    import com.aliyun.oss.*;
    import com.aliyun.oss.internal.OSSHeaders;
    import com.aliyun.oss.model.GeneratePresignedUrlRequest;
    import com.aliyun.oss.model.StorageClass;
    import org.apache.http.HttpEntity;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpPut;
    import org.apache.http.entity.FileEntity;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import java.io.*;
    import java.net.URL;
    import java.util.*;
    
    public class Demo {
        public static void main(String[] args) throws Throwable {
            // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
            String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
            // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
            String accessKeyId = "yourAccessKeyId";
            String accessKeySecret = "yourAccessKeySecret";
            // 从STS服务获取的安全令牌(SecurityToken)。
            String securityToken = "yourSecurityToken";
            // 填写Bucket名称,例如examplebucket。
            String bucketName = "examplebucket";
            // 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。
            String objectName = "exampleobject.txt";
            // 填写本地文件的完整路径。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件。
            String pathName = "D:\\localpath\\examplefile.txt";
    
            // 从STS服务获取临时访问凭证后,您可以通过临时访问密钥和安全令牌生成OSSClient(既这里的accessKeyId和accessKeySecret为STS服务返回的)。
            // 使用STS服务创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);
            // 不使用STS服务创建OSSClient实例。
            // OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    
            // 设置请求头。
            Map<String, String> headers = new HashMap<String, String>();
            /*// 指定Object的存储类型。
            headers.put(OSSHeaders.STORAGE_CLASS, StorageClass.Standard.toString());
            // 指定ContentType。
            headers.put(OSSHeaders.CONTENT_TYPE, "text/txt");*/
    
            // 设置用户自定义元信息。
            Map<String, String> userMetadata = new HashMap<String, String>();
            /*userMetadata.put("key1","value1");
            userMetadata.put("key2","value2");*/
    
            URL signedUrl = null;
            try {
                // 指定生成的签名URL过期时间,单位为毫秒。
                Date expiration = new Date(new Date().getTime() + 3600 * 1000);
    
                // 生成签名URL。
                GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectName, HttpMethod.PUT);
                // 设置过期时间。
                request.setExpiration(expiration);
    
                // 将请求头加入到request中。
                request.setHeaders(headers);
                // 添加用户自定义元信息。
                request.setUserMetadata(userMetadata);
    
                // 通过HTTP PUT请求生成签名URL。
                signedUrl = ossClient.generatePresignedUrl(request);
                // 打印签名URL。
                System.out.println("signed url for putObject: " + signedUrl);
    
            } catch (OSSException oe) {
                System.out.println("Caught an OSSException, which means your request made it to OSS, "
                        + "but was rejected with an error response for some reason.");
                System.out.println("Error Message:" + oe.getErrorMessage());
                System.out.println("Error Code:" + oe.getErrorCode());
                System.out.println("Request ID:" + oe.getRequestId());
                System.out.println("Host ID:" + oe.getHostId());
            } catch (ClientException ce) {
                System.out.println("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.");
                System.out.println("Error Message:" + ce.getMessage());
            }
    
            // 通过签名URL上传文件,以HttpClients为例说明。
            putObjectWithHttp(signedUrl, pathName, headers, userMetadata);
        }
    
        public static void putObjectWithHttp(URL signedUrl, String pathName, Map<String, String> headers, Map<String, String> userMetadata) throws IOException {
            CloseableHttpClient httpClient = null;
            CloseableHttpResponse response = null;
            try {
                HttpPut put = new HttpPut(signedUrl.toString());
                HttpEntity entity = new FileEntity(new File(pathName));
                put.setEntity(entity);
                // 如果生成签名URL时设置了header参数,例如用户元数据,存储类型等,则调用签名URL上传文件时,也需要将这些参数发送至服务端。如果签名和发送至服务端的不一致,会报签名错误。
                for(Map.Entry header: headers.entrySet()){
                    put.addHeader(header.getKey().toString(),header.getValue().toString());
                }
                for(Map.Entry meta: userMetadata.entrySet()){
                    put.addHeader(meta.getKey().toString(),meta.getValue().toString());
                }
    
                httpClient = HttpClients.createDefault();
    
                response = httpClient.execute(put);
    
                System.out.println("返回上传状态码:"+response.getStatusLine().getStatusCode());
                if(response.getStatusLine().getStatusCode() == 200){
                    System.out.println("使用网络库上传成功");
                }
                System.out.println(response.toString());
            } catch (Exception e){
                e.printStackTrace();
            } finally {
                response.close();
                httpClient.close();
            }
        }
    }       
  • 使用签名URL下载文件

    以下代码用于生成下载的签名URL,并使用签名URL下载文件。

    import com.aliyun.oss.*;
    import com.aliyun.oss.internal.OSSHeaders;
    import com.aliyun.oss.model.GeneratePresignedUrlRequest;
    import com.aliyun.oss.model.StorageClass;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import java.io.*;
    import java.net.URL;
    import java.util.*;
    
    public class Demo {
        public static void main(String[] args) throws Throwable {
            // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
            String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
            // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
            String accessKeyId = "yourAccessKeyId";
            String accessKeySecret = "yourAccessKeySecret";
            // 从STS服务获取的安全令牌(SecurityToken)。
            String securityToken = "yourSecurityToken";
            // 填写Bucket名称,例如examplebucket。
            String bucketName = "examplebucket";
            // 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。
            String objectName = "exampleobject.txt";
            // 填写下载到本地文件的完整路径。
            String pathName = "D:\\localpath\\examplefile.txt";
    
    
            // 从STS服务获取临时访问凭证后,您可以通过临时访问密钥和安全令牌生成OSSClient(既这里的accessKeyId和accessKeySecret为STS服务返回的)。
            // 使用STS创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);
            // 不使用STS创建OSSClient实例。
            // OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    
            // 设置请求头。
            Map<String, String> headers = new HashMap<String, String>();
            /*// 指定Object的存储类型。
            headers.put(OSSHeaders.STORAGE_CLASS, StorageClass.Standard.toString());
            // 指定ContentType。
            headers.put(OSSHeaders.CONTENT_TYPE, "text/txt");*/
    
            // 设置用户自定义元信息。
            Map<String, String> userMetadata = new HashMap<String, String>();
            /*userMetadata.put("key1","value1");
            userMetadata.put("key2","value2");*/
    
            URL signedUrl = null;
            try {
                // 指定生成的签名URL过期时间,单位为毫秒。
                Date expiration = new Date(new Date().getTime() + 3600 * 1000);
    
                // 生成签名URL。
                GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectName, HttpMethod.GET);
                // 设置过期时间。
                request.setExpiration(expiration);
    
                // 将请求头加入到request中。
                request.setHeaders(headers);
                // 添加用户自定义元信息。
                request.setUserMetadata(userMetadata);
    
                // 设置查询参数。
                // Map<String, String> queryParam = new HashMap<String, String>();
                // 指定IP地址或者IP地址段。
                // queryParam.put("x-oss-ac-source-ip","110.191.179.0");
                // 指定子网掩码中1的个数。
                // queryParam.put("x-oss-ac-subnet-mask","32");
                // 指定VPC ID。
                // queryParam.put("x-oss-ac-vpc-id","vpc-12345678");
                // 指定是否允许转发请求。
                // queryParam.put("x-oss-ac-forward-allow","true");
                // request.setQueryParameter(queryParam);
    
                // 设置单链接限速,单位为bit,例如限速100 KB/s。
                // request.setTrafficLimit(100 * 1024 * 8);
    
                // 通过HTTP GET请求生成签名URL。
                signedUrl = ossClient.generatePresignedUrl(request);
                // 打印签名URL。
                System.out.println("signed url for putObject: " + signedUrl);
            } catch (OSSException oe) {
                System.out.println("Caught an OSSException, which means your request made it to OSS, "
                        + "but was rejected with an error response for some reason.");
                System.out.println("Error Message:" + oe.getErrorMessage());
                System.out.println("Error Code:" + oe.getErrorCode());
                System.out.println("Request ID:" + oe.getRequestId());
                System.out.println("Host ID:" + oe.getHostId());
            } catch (ClientException ce) {
                System.out.println("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.");
                System.out.println("Error Message:" + ce.getMessage());
            }
    
            // 通过签名URL下载文件,以HttpClients为例说明。
            getObjectWithHttp(signedUrl, pathName, headers, userMetadata);
        }
    
        public static void getObjectWithHttp(URL signedUrl, String pathName, Map<String, String> headers, Map<String, String> userMetadata) throws IOException {
            CloseableHttpClient httpClient = null;
            CloseableHttpResponse response = null;
            try {
                HttpGet get = new HttpGet(signedUrl.toString());
    
                // 如果生成签名URL时设置了header参数,例如用户元数据,存储类型等,则调用签名URL下载文件时,也需要将这些参数发送至服务端。如果签名和发送至服务端的不一致,会报签名错误。
                for(Map.Entry header: headers.entrySet()){
                    get.addHeader(header.getKey().toString(),header.getValue().toString());
                }
                for(Map.Entry meta: userMetadata.entrySet()){
                    get.addHeader(meta.getKey().toString(),meta.getValue().toString());
                }
    
                httpClient = HttpClients.createDefault();
                response = httpClient.execute(get);
    
                System.out.println("返回下载状态码:"+response.getStatusLine().getStatusCode());
                if(response.getStatusLine().getStatusCode() == 200){
                    System.out.println("使用网络库下载成功");
                }
                System.out.println(response.toString());
    
                // 保存文件到磁盘。
                saveFileToLocally(response.getEntity().getContent(), pathName);
            } catch (Exception e){
                e.printStackTrace();
            } finally {
                response.close();
                httpClient.close();
            }
        }
    
        public static void saveFileToLocally(InputStream inputStream, String pathName) throws IOException {
            DataInputStream in = null;
            OutputStream out = null;
            try {
                in = new DataInputStream(inputStream);
                out = new DataOutputStream(new FileOutputStream(pathName));
                int bytes = 0;
                byte[] bufferOut = new byte[1024];
                while ((bytes = in.read(bufferOut)) != -1) {
                    out.write(bufferOut, 0, bytes);
                }
            } catch (Exception e){
                e.printStackTrace();
            } finally {
                in.close();
                out.close();
            }
        }
    }