本文档通过一个示例向您介绍如何在本地 Spring Cloud 应用中实现对象存储,并将该应用托管到 EDAS 中。

为什么使用 OSS

OSS 是阿里云提供的海量、安全、低成本、高可靠的云存储服务。具有与平台无关的 RESTful API 接口,您可以在 Spring Cloud 开发的应用中存储和访问任意类型的数据。

准备工作

在应用中实现对象存储功能前,您需要先使用您的阿里云账号在 OSS 创建存储空间。

  1. 开通OSS服务
  2. 创建存储空间

在本地实现对象存储

  1. 创建一个 Maven 工程,命名为oss-example
  2. pom.xml文件中添加如下依赖。

    以 Spring Boot 2.1.4.RELEASE 和 Spring Cloud Greenwich.SR1 为例。

     <parent>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-parent</artifactId>
         <version>2.1.4.RELEASE</version>
         <relativePath/>
     </parent>
    
      <dependencies>
         <dependency>
             <groupId>com.alibaba.cloud</groupId>
             <artifactId>spring-cloud-starter-alicloud-oss</artifactId>
             <version>2.1.1.RELEASE</version>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
         </dependency>
     </dependencies>
    
     <dependencyManagement>
         <dependencies>
             <dependency>
                 <groupId>org.springframework.cloud</groupId>
                 <artifactId>spring-cloud-dependencies</artifactId>
                 <version>Finchley.SR1</version>
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
         </dependencies>
     </dependencyManagement>                        
    说明
    • 如果您需要选择使用 Spring Boot 1.x 的版本,请使用 Spring Boot 1.5.x 和 Spring Cloud Edgware 版本,对应的 Spring Cloud Alibaba 版本为 1.5.1.RELEASE。
    • Spring Boot 1.x 版本的生命周期已结束,推荐使用 Spring Boot 新版本开发您的应用。
  3. src/main/java下创建一个 package,如spring.cloud.alicloud.oss
  4. 在 packagespring.cloud.alicloud.oss下创建oss-example的启动类OssApplication
        package spring.cloud.alicloud.oss;
    
        import com.aliyun.oss.OSS;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.boot.ApplicationArguments;
        import org.springframework.boot.ApplicationRunner;
        import org.springframework.boot.SpringApplication;
        import org.springframework.boot.autoconfigure.SpringBootApplication;
        import org.springframework.context.annotation.Bean;
    
        import java.net.URISyntaxException;
    
        @SpringBootApplication
        public class OssApplication {
            public static final String BUCKET_NAME = "test-bucket";
            public static void main(String[] args) throws URISyntaxException {
                SpringApplication.run(OssApplication.class, args);
            }
            @Bean
            public AppRunner appRunner() {
                return new AppRunner();
            }
            class AppRunner implements ApplicationRunner {
                @Autowired
                private OSS ossClient;
                @Override
                public void run(ApplicationArguments args) throws Exception {
                    try {
                        if (!ossClient.doesBucketExist(BUCKET_NAME)) {
                            ossClient.createBucket(BUCKET_NAME);
                        }
                    } catch (Exception e) {
                        System.err.println("oss handle bucket error: " + e.getMessage());
                        System.exit(-1);
                    }
                }
            }
        }                        
  5. src/main/resources路径下再添加一个用于上传的示例文件oss-test.json
     {
       "name": "oss-test"
     }                        
  6. 在 packagespring.cloud.alicloud.oss下创建类OssController并添加配置,包含上传、下载,以及使用 Spring 的 Resouce 规范获取文件的功能。
        package spring.cloud.alicloud.oss;
    
        import com.aliyun.oss.OSS;
        import com.aliyun.oss.common.utils.IOUtils;
        import com.aliyun.oss.model.OSSObject;
        import org.apache.commons.codec.CharEncoding;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.beans.factory.annotation.Value;
        import org.springframework.core.io.Resource;
        import org.springframework.util.StreamUtils;
        import org.springframework.web.bind.annotation.GetMapping;
        import org.springframework.web.bind.annotation.RestController;
    
        import java.nio.charset.Charset;
    
        @RestController
        public class OssController {
            @Autowired
            private OSS ossClient;
            @Value("oss://" + OssApplication.BUCKET_NAME + "/oss-test.json")
            private Resource file;
            @GetMapping("/upload")
            public String upload() {
                try {
                    ossClient.putObject(OssApplication.BUCKET_NAME, "oss-test.json", this
                            .getClass().getClassLoader().getResourceAsStream("oss-test.json"));
                } catch (Exception e) {
                    e.printStackTrace();
                    return "upload fail: " + e.getMessage();
                }
                return "upload success";
            }
            @GetMapping("/file-resource")
            public String fileResource() {
                try {
                    return "get file resource success. content: " + StreamUtils.copyToString(
                            file.getInputStream(), Charset.forName(CharEncoding.UTF_8));
                } catch (Exception e) {
                    e.printStackTrace();
                    return "get resource fail: " + e.getMessage();
                }
            }
            @GetMapping("/download")
            public String download() {
                try {
                    OSSObject ossObject = ossClient.getObject(OssApplication.BUCKET_NAME, "oss-test.json");
                    return "download success, content: " + IOUtils
                            .readStreamAsString(ossObject.getObjectContent(), CharEncoding.UTF_8);
                } catch (Exception e) {
                    e.printStackTrace();
                    return "download fail: " + e.getMessage();
                }
            }
        }                        
  7. 获取 Access Key ID、Access Key Secret 和 Endpoint,并在本地添加配置。
    1. 登录安全信息管理页面,获取 Access Key ID 和 Access Key Secret。
    2. 参考访问域名和数据中心,按创建存储空间的地域获取 Endpoint。
    3. src/main/resources路径下创建application.properties文件,并添加 Access Key ID、Access Key Secret 和 Endpoint 配置。
      spring.application.name=oss-example
      server.port=18084
      # 填写 Access Key ID
      spring.cloud.alicloud.access-key=xxxxx
      # 填写 Access Key Secret
      spring.cloud.alicloud.secret-key=xxxxx
      # 填写 Endpoint
      spring.cloud.alicloud.oss.endpoint=xxx.aliyuncs.com
      management.endpoints.web.exposure.include=*                                
  8. 执行OssApplication中的 main 函数,启动服务。

结果验证

  1. 在浏览器中访问 http://127.0.0.1:18084/upload
    如果提示upload success,则说明示例文件oss-test.json上传成功。否则,请检查本地代码,排查问题,然后再次执行OssApplication中的 main 函数,启动服务。
  2. 登录 OSS 控制台,进入您创建并上传文件的 Bucket,然后在顶部单击文件管理,查看是否有示例文件。
    如果看到 oss-test.json,则说明上传成功。否则,请检查本地代码,排查问题,然后再次执行 OssApplication 中的 main 函数,启动服务。
  3. 在浏览器访问 http://127.0.0.1:18084/upload 即可下载文件,会得到 oss-test.json 的文件内容。
     {
       "name": "oss-test"
     }                        
  4. 在浏览器访问 http://127.0.0.1:18084/file-resource 即可获得示例文件oss-test.json的内容。
     {
       "name": "oss-test"
     }                        

部署应用到 EDAS

Spring Cloud AliCloud OSS 在设计之初就考虑到了从开发环境迁移到 EDAS 的场景,您可以直接将应用部署到 EDAS 中,无需修改任何代码和配置。部署方式和详细步骤请参考应用部署概述(K8s 集群)应用部署概述(ECS 集群)