阿里云OSS存储

一、资料链接

   阿里云oss 文档

   阿里云oss API   

二、入门demo 下载地址

public class HelloOSS {
    static Logger logger = Logger.getLogger(HelloOSS.class);

    // endpoint是访问OSS的域名。如果您已经在OSS的控制台上 创建了Bucket,请在控制台上查看域名。
    // 如果您还没有创建Bucket,endpoint选择请参看文档中心的“开发人员指南 > 基本概念 > 访问域名”,
    // 链接地址是:https://help.aliyun.com/document_detail/oss/user_guide/oss_concept/endpoint.html?spm=5176.docoss/user_guide/endpoint_region
    // endpoint的格式形如“http://oss-cn-hangzhou.aliyuncs.com/”,注意http://后不带bucket名称,
    // 比如“http://bucket-name.oss-cn-hangzhou.aliyuncs.com”,是错误的endpoint,请去掉其中的“bucket-name”。
    private static String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";

    // accessKeyId和accessKeySecret是OSS的访问密钥,您可以在控制台上创建和查看,
    // 创建和查看访问密钥的链接地址是:https://ak-console.aliyun.com/#/。
    // 注意:accessKeyId和accessKeySecret前后都没有空格,从控制台复制时请检查并去除多余的空格。
    private static String accessKeyId = "<yourAccessKeyId>";
    private static String accessKeySecret = "<yourAccessKeySecret>";

    // Bucket用来管理所存储Object的存储空间,详细描述请参看“开发人员指南 > 基本概念 > OSS基本概念介绍”。
    // Bucket命名规范如下:只能包括小写字母,数字和短横线(-),必须以小写字母或者数字开头,长度必须在3-63字节之间。
    private static String bucketName = "<yourBucketName>";

    // Object是OSS存储数据的基本单元,称为OSS的对象,也被称为OSS的文件。详细描述请参看“开发人员指南 > 基本概念 > OSS基本概念介绍”。
    // Object命名规范如下:使用UTF-8编码,长度必须在1-1023字节之间,不能以“/”或者“\”字符开头。
    private static String firstKey = "my-first-key";

    public static void main(String[] args) {

        // 日志配置,OSS Java SDK使用log4j记录错误信息。示例程序会在工程目录下生成“oss-demo.log”日志文件,默认日志级别是INFO。
        // 日志的配置文件是“conf/log4j.properties”,如果您不需要日志,可以没有日志配置文件和下面的日志配置。
        PropertyConfigurator.configure("conf/log4j.properties");

        logger.info("Started");

        // 生成OSSClient,您可以指定一些参数,详见“SDK手册 > Java-SDK > 初始化”,
        // 链接地址是:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/init.html?spm=5176.docoss/sdk/java-sdk/get-start
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);

        try {

            // 判断Bucket是否存在。详细请参看“SDK手册 > Java-SDK > 管理Bucket”。
            // 链接地址是:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/manage_bucket.html?spm=5176.docoss/sdk/java-sdk/init
            if (ossClient.doesBucketExist(bucketName)) {
                System.out.println("您已经创建Bucket:" + bucketName + "。");
            } else {
                System.out.println("您的Bucket不存在,创建Bucket:" + bucketName + "。");
                // 创建Bucket。详细请参看“SDK手册 > Java-SDK > 管理Bucket”。
                // 链接地址是:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/manage_bucket.html?spm=5176.docoss/sdk/java-sdk/init
                ossClient.createBucket(bucketName);
            }

            // 查看Bucket信息。详细请参看“SDK手册 > Java-SDK > 管理Bucket”。
            // 链接地址是:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/manage_bucket.html?spm=5176.docoss/sdk/java-sdk/init
            BucketInfo info = ossClient.getBucketInfo(bucketName);
            System.out.println("Bucket " + bucketName + "的信息如下:");
            System.out.println("\t数据中心:" + info.getBucket().getLocation());
            System.out.println("\t创建时间:" + info.getBucket().getCreationDate());
            System.out.println("\t用户标志:" + info.getBucket().getOwner());

            // 把字符串存入OSS,Object的名称为firstKey。详细请参看“SDK手册 > Java-SDK > 上传文件”。
            // 链接地址是:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/upload_object.html?spm=5176.docoss/user_guide/upload_object
            InputStream is = new ByteArrayInputStream("Hello OSS".getBytes());
            ossClient.putObject(bucketName, firstKey, is);
            System.out.println("Object:" + firstKey + "存入OSS成功。");

            // 下载文件。详细请参看“SDK手册 > Java-SDK > 下载文件”。
            // 链接地址是:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/download_object.html?spm=5176.docoss/sdk/java-sdk/manage_object
            OSSObject ossObject = ossClient.getObject(bucketName, firstKey);
            InputStream inputStream = ossObject.getObjectContent();
            StringBuilder objectContent = new StringBuilder();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            while (true) {
                String line = reader.readLine();
                if (line == null)
                    break;
                objectContent.append(line);
            }
            inputStream.close();
            System.out.println("Object:" + firstKey + "的内容是:" + objectContent);

            // 文件存储入OSS,Object的名称为fileKey。详细请参看“SDK手册 > Java-SDK > 上传文件”。
            // 链接地址是:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/upload_object.html?spm=5176.docoss/user_guide/upload_object
            String fileKey = "README.md";
            ossClient.putObject(bucketName, fileKey, new File("README.md"));
            System.out.println("Object:" + fileKey + "存入OSS成功。");

            // 查看Bucket中的Object。详细请参看“SDK手册 > Java-SDK > 管理文件”。
            // 链接地址是:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/manage_object.html?spm=5176.docoss/sdk/java-sdk/manage_bucket
            ObjectListing objectListing = ossClient.listObjects(bucketName);
            List<OSSObjectSummary> objectSummary = objectListing.getObjectSummaries();
            System.out.println("您有以下Object:");
            for (OSSObjectSummary object : objectSummary) {
                System.out.println("\t" + object.getKey());
            }

            // 删除Object。详细请参看“SDK手册 > Java-SDK > 管理文件”。
            // 链接地址是:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/manage_object.html?spm=5176.docoss/sdk/java-sdk/manage_bucket
            ossClient.deleteObject(bucketName, firstKey);
            System.out.println("删除Object:" + firstKey + "成功。");
            ossClient.deleteObject(bucketName, fileKey);
            System.out.println("删除Object:" + fileKey + "成功。");

        } catch (OSSException oe) {
            oe.printStackTrace();
        } catch (ClientException ce) {
            ce.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            ossClient.shutdown();
        }

        logger.info("Completed");
    }

}

三、oss基础学习

这个demo是阿里云官方提供的demo,那么我们开始一步步分析下他的代码。来帮助我们更好的学习sso。

3.1 创建

首先从创建 OSSClient 开始,点进源码,可以发现创建ossClient有多种创建方式。

public class OSSClient implements OSS {
    private CredentialsProvider credsProvider;
    private URI endpoint;
    private ServiceClient serviceClient;
    private OSSBucketOperation bucketOperation;
    private OSSObjectOperation objectOperation;
    private OSSMultipartOperation multipartOperation;
    private CORSOperation corsOperation;
    private OSSUploadOperation uploadOperation;
    private OSSDownloadOperation downloadOperation;
    private LiveChannelOperation liveChannelOperation;
    private OSSUdfOperation udfOperation;

    /** @deprecated   域名默认指向华东地区的(杭州) */
    @Deprecated
    public OSSClient(String accessKeyId, String secretAccessKey) {
        this("http://oss.aliyuncs.com", (CredentialsProvider)(new DefaultCredentialProvider(accessKeyId, secretAccessKey)));
    }

    public OSSClient(String endpoint, String accessKeyId, String secretAccessKey) {
        this(endpoint, (CredentialsProvider)(new DefaultCredentialProvider(accessKeyId, secretAccessKey)), (ClientConfiguration)null);
    }

    // 暂时还不知道,看名字定义估计是传入一个token来进行安全认证的
    public OSSClient(String endpoint, String accessKeyId, String secretAccessKey, String securityToken) {
        this(endpoint, (CredentialsProvider)(new DefaultCredentialProvider(accessKeyId, secretAccessKey, securityToken)), (ClientConfiguration)null);
    }
    
    // 需要传入ClientConfiguration配置文件,可配置代理、连接超时、最大连接数等参数。
    public OSSClient(String endpoint, String accessKeyId, String secretAccessKey, ClientConfiguration config) {
        this(endpoint, (CredentialsProvider)(new DefaultCredentialProvider(accessKeyId, secretAccessKey)), (ClientConfiguration)config);
    }
    
    public OSSClient(String endpoint, String accessKeyId, String secretAccessKey, String securityToken, ClientConfiguration config) {
        this(endpoint, (CredentialsProvider)(new DefaultCredentialProvider(accessKeyId, secretAccessKey, securityToken)), (ClientConfiguration)config);
    }

    public OSSClient(String endpoint, CredentialsProvider credsProvider) {
        this(endpoint, (CredentialsProvider)credsProvider, (ClientConfiguration)null);
    }

    public OSSClient(String endpoint, CredentialsProvider credsProvider, ClientConfiguration config) {
        this.credsProvider = credsProvider;
        config = config == null ? new ClientConfiguration() : config;
        if (config.isRequestTimeoutEnabled()) {
            this.serviceClient = new TimeoutServiceClient(config);
        } else {
            this.serviceClient = new DefaultServiceClient(config);
        }

        this.initOperations();
        this.setEndpoint(endpoint);
    }

创建完ossClient之后就需要创建存储空间了。毕竟我们的object都是存放到存储空间中的。

使用ossClient创建存储空间的方法有两种

/**
 *  直接命名存储空间的name来创建
**/
  
public Bucket createBucket(String bucketName) throws OSSException, ClientException {
        return this.createBucket(new CreateBucketRequest(bucketName));
    }

/**
 * 如果创建存储空间的同时需要指定存储类型以及数据容灾类型
 * 则需要 CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
 * 然后传入createBucketRequest 来创建
**/
    public Bucket createBucket(CreateBucketRequest createBucketRequest) throws OSSException, ClientException {
        return this.bucketOperation.createBucket(createBucketRequest);
    }

3.2 文件上传

接下来就是基础的操作了----上传文件

阿里云将上传文件分为五大类:简单上传、表单上传、追加上传、断点断传上传、分片上传

简单上传其实就是上传单个文件,分为流式上传文件上传

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

            // 上传字符串。
            {
                // 创建PutObjectRequest对象。
                String content = "Hello OSS";

                // <yourObjectName>表示上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。
                PutObjectRequest putObjectRequest = new PutObjectRequest("<yourBucketName>", "<yourObjectName>", new ByteArrayInputStream(content.getBytes()));

                ossClient.putObject(putObjectRequest);
            }

            // 上传Byte数组。
            {
                byte[] content = "Hello OSS".getBytes();
                ossClient.putObject("<yourBucketName>", "<yourObjectName>", new ByteArrayInputStream(content));
            }

            // 上传网络流。
            {
                InputStream inputStream = new URL("https://www.aliyun.com/").openStream();
                ossClient.putObject("<yourBucketName>", "<yourObjectName>", inputStream);

            }

            // 上传文件流。
            {
                InputStream inputStream = new FileInputStream("<yourlocalFile>");
                ossClient.putObject("<yourBucketName>", "<yourObjectName>", inputStream);
            }

            // 上传文件
            {
                // 创建PutObjectRequest对象。
                PutObjectRequest putObjectRequest = new PutObjectRequest("<yourBucketName>", "<yourObjectName>", new File("<yourLocalFile>"));

                ossClient.putObject(putObjectRequest);
            }

从代码中可以看出,简单上传主要就是上传InputStreamPutObjectRequest对象。

表单上传:

       表单上传是直接将表单内容传到阿里云oss存储服务器中。(划重点

public class PostObjectSample {
    // 上传文件
    private String localFilePath = "<yourLocalFile>";
    // Endpoint以杭州为例,其它Region请按实际情况填写。
    private String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
    // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
    private String accessKeyId = "<yourAccessKeyId>";
    private String accessKeySecret = "<yourAccessKeySecret>";
    // 存储空间名称
    private String bucketName = "<yourBucketName>";
    // 文件名称
    private String objectName = "<yourObjectName>";
    /**
     * 表单上传
     * @throws Exception
     */
    private void PostObject() throws Exception {
        // 在URL中添加存储空间名称,添加后URL如下:http://yourBucketName.oss-cn-hangzhou.aliyuncs.com
        String urlStr = endpoint.replace("http://", "http://" + bucketName+ ".");
        // 表单Map。
        Map<String, String> formFields = new LinkedHashMap<String, String>();
        // 设置文件名称。
        formFields.put("key", this.objectName);
        // 设置Content-Disposition。
        formFields.put("Content-Disposition", "attachment;filename="
                + localFilePath);
        // 设置回调参数。
        Callback callback = new Callback();
        // 设置回调服务器地址,如http://oss-demo.aliyuncs.com:23450或http://127.0.0.1:9090。
        callback.setCallbackUrl("<yourCallbackServerUrl>");
        // 设置回调请求消息头中Host的值,如oss-cn-hangzhou.aliyuncs.com。
        callback.setCallbackHost("<yourCallbackServerHost>");
        // 设置发起回调时请求body的值。
        callback.setCallbackBody("{\\\"mimeType\\\":${mimeType},\\\"size\\\":${size}}");
        // 设置发起回调请求的Content-Type。
        callback.setCalbackBodyType(CalbackBodyType.JSON);
        // 设置发起回调请求的自定义参数,由Key和Value组成,Key必须以x:开始,且必须为小写。
        callback.addCallbackVar("x:var1", "value1");
        callback.addCallbackVar("x:var2", "value2");
        // 在表单Map中设置回调参数。
        setCallBack(formFields, callback);
        // 设置OSSAccessKeyId。
        formFields.put("OSSAccessKeyId", accessKeyId);
        String policy = "{\"expiration\": \"2120-01-01T12:00:00.000Z\",\"conditions\": [[\"content-length-range\", 0, 104857600]]}";
        String encodePolicy = new String(Base64.encodeBase64(policy.getBytes()));
        // 设置policy。
        formFields.put("policy", encodePolicy);
        // 生成签名。
        String signaturecom = com.aliyun.oss.common.auth.ServiceSignature.create().computeSignature(accessKeySecret, encodePolicy);
        // 设置签名。
        formFields.put("Signature", signaturecom);
        String ret = formUpload(urlStr, formFields, localFilePath);
        System.out.println("Post Object [" + this.objectName + "] to bucket [" + bucketName + "]");
        System.out.println("post reponse:" + ret);
    }
    private static String formUpload(String urlStr, Map<String, String> formFields, String localFile)
            throws Exception {
        String res = "";
        HttpURLConnection conn = null;
        String boundary = "9431149156168";
        try {
            URL url = new URL(urlStr);
            conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(30000);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("User-Agent", 
                    "Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)");
            // 设置MD5值。MD5值是由整个body计算得出的。
            conn.setRequestProperty("Content-MD5", "<yourContentMD5>");
            conn.setRequestProperty("Content-Type",
                    "multipart/form-data; boundary=" + boundary);
            OutputStream out = new DataOutputStream(conn.getOutputStream());
            // 遍历读取表单Map中的数据,将数据写入到输出流中。
            if (formFields != null) {
                StringBuffer strBuf = new StringBuffer();
                Iterator<Entry<String, String>> iter = formFields.entrySet().iterator();
                int i = 0;
                while (iter.hasNext()) {
                    Entry<String, String> entry = iter.next();
                    String inputName = entry.getKey();
                    String inputValue = entry.getValue();
                    if (inputValue == null) {
                        continue;
                    }
                    if (i == 0) {
                        strBuf.append("--").append(boundary).append("\r\n");
                        strBuf.append("Content-Disposition: form-data; name=\""
                                + inputName + "\"\r\n\r\n");
                        strBuf.append(inputValue);
                    } else {
                        strBuf.append("\r\n").append("--").append(boundary).append("\r\n");
                        strBuf.append("Content-Disposition: form-data; name=\""
                                + inputName + "\"\r\n\r\n");
                        strBuf.append(inputValue);
                    }
                    i++;
                }
                out.write(strBuf.toString().getBytes());
            }
            // 读取文件信息,将要上传的文件写入到输出流中。
            File file = new File(localFile);
            String filename = file.getName();
            String contentType = new MimetypesFileTypeMap().getContentType(file);
            if (contentType == null || contentType.equals("")) {
                contentType = "application/octet-stream";
            }
            StringBuffer strBuf = new StringBuffer();
            strBuf.append("\r\n").append("--").append(boundary)
                    .append("\r\n");
            strBuf.append("Content-Disposition: form-data; name=\"file\"; "
                    + "filename=\"" + filename + "\"\r\n");
            strBuf.append("Content-Type: " + contentType + "\r\n\r\n");
            out.write(strBuf.toString().getBytes());
            DataInputStream in = new DataInputStream(new FileInputStream(file));
            int bytes = 0;
            byte[] bufferOut = new byte[1024];
            while ((bytes = in.read(bufferOut)) != -1) {
                out.write(bufferOut, 0, bytes);
            }
            in.close();
            byte[] endData = ("\r\n--" + boundary + "--\r\n").getBytes();
            out.write(endData);
            out.flush();
            out.close();
            // 读取返回数据。
            strBuf = new StringBuffer();
            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line = null;
            while ((line = reader.readLine()) != null) {
                strBuf.append(line).append("\n");
            }
            res = strBuf.toString();
            reader.close();
            reader = null;
        } catch (Exception e) {
            System.err.println("Send post request exception: " + e);
            throw e;
        } finally {
            if (conn != null) {
                conn.disconnect();
                conn = null;
            }
        }
        return res;
    }
     private static void setCallBack(Map<String, String> formFields, Callback callback) {
        if (callback != null) {
            String jsonCb = OSSUtils.jsonizeCallback(callback);
            String base64Cb = BinaryUtil.toBase64String(jsonCb.getBytes());
            formFields.put("callback", base64Cb);
            if (callback.hasCallbackVar()) {
                Map<String, String> varMap = callback.getCallbackVar();
                for (Entry<String, String> entry : varMap.entrySet()) {
                    formFields.put(entry.getKey(), entry.getValue());
                }
            }
        }
    }
    public static void main(String[] args) throws Exception {
        PostObjectSample ossPostObject = new PostObjectSample();
        ossPostObject.PostObject();
    }
}

追加上传

   简单上传表单上传断点续传上传等,创建的Object都是Normal类型,这种Object在上传结束之后内容就是固定的,只能读取,不能修改。如果Object内容发生了改变,只能重新上传同名的Object来覆盖之前的内容。而追加上传(Append Object),是在一个Object后面直接追加内容。通过这种方式操作的Object的类型为Appendable Object,

// 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>";

String content1 = "Hello OSS A \n";
String content2 = "Hello OSS B \n";
String content3 = "Hello OSS C \n";

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

ObjectMetadata meta = new ObjectMetadata();
// 指定上传的内容类型。
meta.setContentType("text/plain");

// 通过AppendObjectRequest设置多个参数。
AppendObjectRequest appendObjectRequest = new AppendObjectRequest("<yourBucketName>", "<yourObjectName>", new ByteArrayInputStream(content1.getBytes()),meta);

// 通过AppendObjectRequest设置单个参数。
// 设置存储空间名称。
//appendObjectRequest.setBucketName("<yourBucketName>");
// 设置文件名称。
//appendObjectRequest.setKey("<yourObjectName>");
// 设置待追加的内容。有两种可选类型:InputStream类型和File类型。这里为InputStream类型。
//appendObjectRequest.setInputStream(new ByteArrayInputStream(content1.getBytes()));
// 设置待追加的内容。有两种可选类型:InputStream类型和File类型。这里为File类型。
//appendObjectRequest.setFile(new File("<yourLocalFile>"));
// 指定文件的元信息,第一次追加时有效。
//appendObjectRequest.setMetadata(meta);

// 第一次追加。
// 设置文件的追加位置。
appendObjectRequest.setPosition(0L);
AppendObjectResult appendObjectResult = ossClient.appendObject(appendObjectRequest);
// 文件的64位CRC值。此值根据ECMA-182标准计算得出。
System.out.println(appendObjectResult.getObjectCRC());

// 第二次追加。
// nextPosition指明下一次请求中应当提供的Position,即文件当前的长度。
appendObjectRequest.setPosition(appendObjectResult.getNextPosition());
appendObjectRequest.setInputStream(new ByteArrayInputStream(content2.getBytes()));
appendObjectResult = ossClient.appendObject(appendObjectRequest);

// 第三次追加。
appendObjectRequest.setPosition(appendObjectResult.getNextPosition());
appendObjectRequest.setInputStream(new ByteArrayInputStream(content3.getBytes()));
appendObjectResult = ossClient.appendObject(appendObjectRequest);

// 关闭OSSClient。
ossClient.shutdown();
		

断点上传和分片上传:

     将要上传的文件分成若干个分片(Part)分别上传,所有分片都上传完成后,将所有分片合并成完整的文件,完成整个文件的上传。

     适用场景:恶劣的网络环境(如手机端)、加速上传(需要上传的文件很大时)、流式上传(不确定上传的文件大小时)

      PS:大小限制:在这种上传方式下,Object的大小是由Part来决定的,最大支持10000块Part。每块Part最小100KB(最后一块可以比100KB小),最大5GB。Object的大小不能超过48.8TB。

     其他上传方式单个文件不能超过5gb。

授权给第三方上传:

    就是上传时将文件直接上传给oss存储而不是服务器。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值