1.对象存储OSS(Object Storage Service)

对象存储可以简单理解为用来存储图片、音频、视频等非结构化数据的数据池。相对于云服务器,具有读写速度快,利于分享的特点。提供对象存储服务的平台有七牛云,阿里云和亚马逊等。

阿里云对象存储OSS(Object Storage Service)是一款海量、安全、低成本、高可靠的云存储服务,提供99.9999999999%(12个9)的数据持久性,99.995%的数据可用性。多种存储类型供选择,全面优化存储成本。

2.OSS购买与配置

在阿里云官网进行购买,新用户貌似可以白嫖三个月

java oss对象存储 短链接方式_java

购买完成之后还需要在控制台左侧找到对象存储OSS,并开通服务。

java oss对象存储 短链接方式_java oss对象存储 短链接方式_02

  开通之后在OSS下创建Bucket

java oss对象存储 短链接方式_java oss对象存储 短链接方式_03

 可以使用访问控制 RAM创建对应的子用户,并在之后使用其提供的accessKeyId 和accessKeySecret 

java oss对象存储 短链接方式_spring boot_04

生成子用户之后的accessKeySecret只会显示一次,记得提前保存好。

java oss对象存储 短链接方式_java oss对象存储 短链接方式_05

3.后端代码

OssUtils:

将传入的MultipartFile file对应的Byte数组上传到目标存储空间bucket中charsBlog/目录下。

MultipartFile一种可以接收使用多种请求方式来进行上传文件的代表形式。(如果使用spring框架来实现项目中的文件上传功能,则MultipartFile是最合适的选择。

上传成功之后访问图片的路径是:OSS管理控制台中对应bucket的外网访问域名 + /bucket下的文件夹 + 文件全名

package com.charsnows.blogapi.utils;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;

/**
 * @author Chars
 */
@Component
public class OssUtils {

    public final String url = "http:// + 外网访问的Bucket域名 + /charsBlog/";
    // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
    @Value("${oss.endpoint}")
    private String endpoint;
    // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
    @Value("${oss.accessKeyId}")
    private String accessKeyId;
    @Value("${oss.accessKeySecret}")
    private String accessKeySecret;
    // 填写Bucket名称,例如examplebucket。
    @Value("${oss.bucketName}")
    private String bucketName;

    public boolean upload(MultipartFile file, String fileName) throws Exception {

        // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
        String objectName = "charsBlog/" + fileName;

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

        try {
            // 填写Byte数组。
            byte[] content = file.getBytes();
            // 创建PutObject请求。
            ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content));
            return 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();
            }
        }
        return false;
    }
}

附:阿里云官方文档给出的源代码:

上传Byte数组

以下代码用于将Byte数组上传到目标存储空间examplebucket中exampledir目录下的exampleobject.txt文件。

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import java.io.ByteArrayInputStream;

public class Demo {

    public static void main(String[] args) throws Exception {
        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
        String accessKeyId = "yourAccessKeyId";
        String accessKeySecret = "yourAccessKeySecret";
        // 填写Bucket名称,例如examplebucket。
        String bucketName = "examplebucket";
        // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
        String objectName = "exampledir/exampleobject.txt";      

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

        try {
            // 填写Byte数组。
            byte[] content = "Hello OSS".getBytes();
            // 创建PutObject请求。
            ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content));
        } 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();
            }
        }
    }
}

UploadController:

调用OssUtils完成上传。

package com.charsnows.blogapi.controller;

import com.charsnows.blogapi.utils.OssUtils;
import com.charsnows.blogapi.vo.Result;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.UUID;

@RestController
@RequestMapping("upload")
public class UploadController {

    @Autowired
    private OssUtils ossUtils;

    @PostMapping
    public Result upload(@RequestParam("image")MultipartFile file) throws Exception {
        //原始文件名称
        String originalFilename = file.getOriginalFilename();
        //随机生成唯一的文件名称
        String fileName = UUID.randomUUID().toString() + "." + StringUtils.substringAfterLast(originalFilename, ".");
        //上传文件
        boolean upload = ossUtils.upload(file, fileName);
        if(upload){
            return Result.success(ossUtils.url + fileName);
        }
        return Result.fail(20001, "上传失败");

    }
}

4.总结

测试页面显示成功,并上传到了对应的bucket中。

java oss对象存储 短链接方式_spring_06

测试途中比较坑的是不知道accessKeySecret只会生成一次,还在控制台又找了半天。最后是使用win + v查看粘贴板才找回来的(因为之前复制过)。如果找不到了只能重新创建一个AccessKey。